|
|
|
![]() |
|
Strumenti |
![]() |
#21 |
Senior Member
Iscritto dal: Nov 2005
Messaggi: 2776
|
Non me ne intendo e quindi magari dico una cavolata, ma non dovrebbe usare queste funzioni?
GetUserProfileDirectory: http://msdn.microsoft.com/en-us/libr.../bb762280.aspx OpenProcessToken: http://msdn.microsoft.com/en-us/libr.../aa379295.aspx GetCurrentProcess: http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx |
![]() |
![]() |
![]() |
#22 |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
ah in c non si può??sicuri??
![]() |
![]() |
![]() |
![]() |
#23 |
Member
Iscritto dal: Nov 2012
Messaggi: 126
|
Si. La libreria standard del C:
- ha la funzione getenv() per recuperare informazioni dall'environment. Puoi usarla per recuperare la variabile "userprofile" ad esempio e poi costruirti la stringa finale che ti interessa del tipo "c:\Users\nome" con "\Desktop" aggiunta in coda; - non ha nessuna funzione con cui puoi cambiare la current directory (in effetti non ha proprio alcun supporto per le directories). Forse sarebbe meglio se ti studiassi un minimo cosa il C mette a disposizione prima di continuare verso il tuo obiettivo. |
![]() |
![]() |
![]() |
#24 | |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#25 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Improved version for Linux:
![]() - Reso il codice thread-safe: http://archive.cert.uni-stuttgart.de.../msg00044.html - Aggiunto puntatore a funzione callback in modo da stampare i dati al di fuori della funzione che effettua la scansione. Così è più flessibile, come nella versione per Windows. Codice:
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <limits.h> #include <stdint.h> #include <sys/types.h> #include <sys/stat.h> #include <dirent.h> #include <unistd.h> void getDirInfo(char *dirName, uint64_t *pDim, int depth, void (*pfnOnChange)(const char *pathName, int depth)) { DIR *dir = NULL; struct dirent entry; struct dirent *entryPtr = NULL; int retval = 0; unsigned count = 0; char pathName[PATH_MAX + 1]; dir = opendir(dirName); if( dir == NULL ) { printf("Error opening %s: %s", dirName, strerror(errno)); return; } depth++; retval = readdir_r(dir, &entry, &entryPtr); while( entryPtr != NULL ) { struct stat entryInfo; if( ( strncmp(entry.d_name, ".", PATH_MAX) == 0 ) || ( strncmp(entry.d_name, "..", PATH_MAX) == 0 ) ) { retval = readdir_r(dir, &entry, &entryPtr); continue; } strncpy(pathName, dirName, PATH_MAX); strncat(pathName, "/", PATH_MAX); strncat(pathName, entry.d_name, PATH_MAX); if( lstat(pathName, &entryInfo) == 0 ) { *pDim += entryInfo.st_size; if( S_ISDIR(entryInfo.st_mode) ) // directory { if ( pfnOnChange ) (*pfnOnChange)(pathName, depth); getDirInfo(pathName, pDim, depth, pfnOnChange); } else if( S_ISREG(entryInfo.st_mode) ) // regular file { //printf("\t%s <> size: %lld bytes\n", pathName, (long long)entryInfo.st_size); if ( pfnOnChange ) (*pfnOnChange)(pathName, depth); } else if( S_ISLNK(entryInfo.st_mode) ) // symbolic link { char targetName[PATH_MAX + 1]; if( readlink(pathName, targetName, PATH_MAX) != -1 ) { //printf("\t%s -> %s\n", pathName, targetName); if ( pfnOnChange ) (*pfnOnChange)(pathName, depth); } else { printf("\t%s -> (invalid symbolic link!)\n", pathName); } } } else { printf("Error lstat %s: %s\n", pathName, strerror(errno)); } retval = readdir_r(dir, &entry, &entryPtr); } depth--; closedir(dir); } void OnChange(const char *pathName, int depth) { printf("%*s%s\n", (depth - 1) * 3, "", pathName); //printf("%s\n", pathName); } int main(int argc, char **argv) { uint64_t dim = 0; if(argc != 2) { fprintf(stdout, "uso: %s <dirpath>\n", argv[0]); fflush(stdout); return -1; } getDirInfo(argv[1], &dim, 0, OnChange); //getDirInfo(argv[1], &dim, 0, NULL); fprintf(stdout, "La dimensione della directory \"%s\" e' di %llu byte.\n", argv[1], (unsigned long long)dim); return 0; } ![]() ![]() Ultima modifica di Vincenzo1968 : 10-03-2013 alle 18:47. |
![]() |
![]() |
![]() |
#26 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Corretto piccolo bug nella versione Windows: non funzionava bene se compilato con: "Use Unicode character set" o "Use Multi-byte character set".
![]() Codice:
#define WIN32_LEAN_AND_MEAN #include <windows.h> #include <tchar.h> #include <stdlib.h> #include <stdio.h> #include <stdint.h> #define ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0])) // Dati usati dalla funzione DirWalkRecurse typedef struct { TCHAR szInitPath[_MAX_DIR]; // Path iniziale TCHAR szCurrPath[_MAX_DIR]; // Path corrente TCHAR szPathParent[_MAX_DIR]; // Path genitore di szCurrPath TCHAR szCurrDir[_MAX_DIR]; // Path temporaneo; ci servirà per la ricerca dei files int nDepth; // Profondità BOOL fRecurse; // impostare a TRUE per ottenere la scansione delle sottodirectory. TCHAR szBuf[1024]; // Buffer per l'output formattato int nIndent; // Contatore per l'indentazione BOOL fOk; // Loop control flag BOOL fIsDir; // Loop control flag WIN32_FIND_DATA FindData; // Informazioni sui file } DIRWALKDATA, *LPDIRWALKDATA; //void getDirInfo(LPCTSTR pszRootPath, BOOL fRecurse, uint64_t *pDim, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA)); BOOL IsChildDir (WIN32_FIND_DATA *lpFindData) { return ( (lpFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (lpFindData->cFileName[0] != __TEXT('.')) ); } BOOL FindNextChildDir (HANDLE hFindFile, WIN32_FIND_DATA *lpFindData) { BOOL fFound = FALSE; do { fFound = FindNextFile(hFindFile, lpFindData); } while (fFound && !IsChildDir(lpFindData)); return(fFound); } HANDLE FindFirstChildDir (LPTSTR szPath, WIN32_FIND_DATA *lpFindData) { BOOL fFound; HANDLE hFindFile = FindFirstFile(szPath, lpFindData); if (hFindFile != INVALID_HANDLE_VALUE) { fFound = IsChildDir(lpFindData); if (!fFound) fFound = FindNextChildDir(hFindFile, lpFindData); if (!fFound) { FindClose(hFindFile); hFindFile = INVALID_HANDLE_VALUE; } } return(hFindFile); } void GetParentDirectory(LPCTSTR szPath, LPTSTR szParent) { size_t nLen; nLen = _tcslen(szPath); _tcscpy(szParent, szPath); if ( szPath[0] == '\\' ) return; while ( nLen > 0 ) { if ( *(szParent + nLen-1) == '\\' ) { *(szParent + nLen-1) = '\0'; break; } --nLen; } } // Percorre la struttura della directory. // Se il campo pDW->fRecurse è TRUE, percorre ricorsivamente anche le sottodirectory.m void DirWalkRecurse (LPDIRWALKDATA pDW, uint64_t *pDim, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA)) { HANDLE hFind; LARGE_INTEGER sz; pDW->szCurrDir[0] = '\0'; pDW->nDepth++; pDW->nIndent = 3 * pDW->nDepth; _stprintf(pDW->szBuf, __TEXT("%*s"), pDW->nIndent, __TEXT("")); // Imposta il buffer alla directory iniziale e chiama la funzione evento // fornita dall'utente. _tcscpy(&pDW->szBuf[pDW->nIndent], pDW->szCurrPath); if ( pfnOnChange ) (*pfnOnChange)(pDW); //printf("pDW->szBuf -----> %s\n", pDW->szBuf); // Inizia a leggere il contenuto della directory iniziale _tcscpy(pDW->szCurrDir, pDW->szCurrPath); _tcscat(pDW->szCurrDir, __TEXT("\\*.*")); hFind = FindFirstFile( pDW->szCurrDir, &pDW->FindData); pDW->fOk = (hFind != INVALID_HANDLE_VALUE); while (pDW->fOk) { pDW->fIsDir = pDW->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; if ( !pDW->fIsDir || (!pDW->fRecurse && IsChildDir(&pDW->FindData)) ) { _stprintf( pDW->szBuf, pDW->fIsDir ? __TEXT("%*s[%s]") : __TEXT("%*s%s"), pDW->nIndent, __TEXT(""), pDW->FindData.cFileName); //*pDim += (pDW->FindData.nFileSizeHigh * (MAXDWORD+1)) + pDW->FindData.nFileSizeLow; sz.LowPart = pDW->FindData.nFileSizeLow; sz.HighPart = pDW->FindData.nFileSizeHigh; *pDim += sz.QuadPart; // Per ogni file ( o sottodirectory ) trovato, // chiamiamo la funzione fornita dall'utente // passandogli i dati relativi tramite il puntatore alla struct pDW. if ( pfnOnChange ) (*pfnOnChange)(pDW); //printf("pDW->szBuf -----> %s\n", pDW->szBuf); } pDW->fOk = FindNextFile(hFind, &pDW->FindData); } if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); // se fRecurse è TRUE, leggiamo ricorsivamente le sottodirectory if (pDW->fRecurse) { // Ottiene la prima directory figlia hFind = FindFirstChildDir( pDW->szCurrDir, &pDW->FindData ); pDW->fOk = (hFind != INVALID_HANDLE_VALUE); while (pDW->fOk) { // Passa alla directory figlia _tcscat(pDW->szCurrPath, __TEXT("\\")); _tcscat(pDW->szCurrPath, pDW->FindData.cFileName); DirWalkRecurse(pDW, pDim, pfnOnChange); // Ritorna alla directory genitore GetParentDirectory(pDW->szCurrPath, pDW->szPathParent); _tcscpy(pDW->szCurrPath, pDW->szPathParent); pDW->fOk = FindNextChildDir(hFind, &pDW->FindData); } if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); } pDW->nDepth--; } // Funzioni esportate ///////////////////////////////////////////////////////////// // Il parametro pszRootPath è il percorso completo della directory da esaminare // Il parametro fRecurse è un valore booleano che indica // se vogliamo leggere anche le sottodirectory. Se impostato a FALSE, la funzione // legge solo la directory passata nel parametro pszRootPath // Il parametro pfnOnChange è un puntatore a una funzione evento che deve essere // implementata dal client ( il programma che utilizza la DLL ) void getDirInfo(LPCTSTR pszRootPath, BOOL fRecurse, uint64_t *pDim, void (CALLBACK *pfnOnChange)(LPDIRWALKDATA)) { DIRWALKDATA DW; DW.szBuf[0] = '\0'; DW.szCurrDir[0] = '\0'; DW.szCurrPath[0] = '\0'; DW.szInitPath[0] = '\0'; DW.szPathParent[0] = '\0'; // nDepth è usato per controllare l'indentazione. Il valore -1 // fa si che il primo livello sia visualizzato allineato a sinistra DW.nDepth = -1; DW.fRecurse = fRecurse; _tcscpy(DW.szInitPath, pszRootPath); _tcscpy(DW.szCurrPath, pszRootPath); // Leggiamo il contenuto della directory passata nel parametro pszRootPath. // Se il parametro fRecurse è TRUE, leggiamo anche le sottodirectory DirWalkRecurse(&DW, pDim, pfnOnChange); } void CALLBACK OnChange(LPDIRWALKDATA pDW) { _tprintf(_TEXT("%s\n"), pDW->szBuf); } //int main(int argc, char* argv[]) int _tmain(int argc, TCHAR *argv[]) { uint64_t dim = 0; if( argc < 2 ) return -1; getDirInfo(argv[1], TRUE, &dim, OnChange); printf("\nLa dimensione della directory \"%s\" e': %llu byte\n", argv[1], (unsigned long long)dim); return 0; } ![]() ![]() Ultima modifica di Vincenzo1968 : 09-03-2013 alle 23:16. |
![]() |
![]() |
![]() |
#27 | |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
#28 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
No, l'api di Windows è cervellotica!
![]() Windows api brain fuck... ![]() Ultima modifica di Vincenzo1968 : 10-03-2013 alle 20:41. |
![]() |
![]() |
![]() |
#29 |
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
Per curiosità, perché è cervellotica la
SetCurrentDirectory http://msdn.microsoft.com/en-us/library/aa365530.aspx ? |
![]() |
![]() |
![]() |
#30 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Confrontala un po' con la api Linux. Guarda cosa c'è da fare per calcolare la dimensione di una file: Codice:
sz.LowPart = pDW->FindData.nFileSizeLow; sz.HighPart = pDW->FindData.nFileSizeHigh; *pDim += sz.QuadPart; Codice:
*pDim += (pDW->FindData.nFileSizeHigh * (MAXDWORD+1)) + pDW->FindData.nFileSizeLow; ![]() |
|
![]() |
![]() |
![]() |
#31 |
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
Cosa c'entra la dimensione del file con quello di cui stiamo parlando ?
Cosa c'entra Linux? ![]() Ultima modifica di lorenzo001 : 11-03-2013 alle 14:56. |
![]() |
![]() |
![]() |
#32 | |||
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
Quote:
Quote:
|
|||
![]() |
![]() |
![]() |
#33 | |
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
Quote:
Che c'entra tutto quello che stai dicendo? P.S. In ogni caso, il calcolo *pDim += (pDW->FindData.nFileSizeHigh * (MAXDWORD+1)) + pDW->FindData.nFileSizeLow; ha solamente una cosa sbagliata ... il fatto che manca il cast di (MAXDWORD+1) ... il calcolo corretto è *pDim += (pDW->FindData.nFileSizeHigh * ((ULONGLONG)(MAXDWORD+1)) + pDW->FindData.nFileSizeLow; Ultima modifica di lorenzo001 : 11-03-2013 alle 15:12. |
|
![]() |
![]() |
![]() |
#34 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Una volta, non ricordo più in quale talk-show, Nosferatu-Sallusti disse: "Cosa c'entra Marcello Dell'Utri con Silvio Berlusconi?".
![]() |
![]() |
![]() |
![]() |
#35 | |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Quote:
*pDim += entryInfo.st_size; ![]() |
|
![]() |
![]() |
![]() |
#36 | ||
Senior Member
Iscritto dal: Jul 2008
Città: Roma
Messaggi: 542
|
Quote:
Quote:
I due valori low e high della struttura di Windows sono comunque due DWORD (a 32 bit) compatibili con i 32 bit (per la sola parte low) e con i 64 se prese insieme. Se poi una semplice moltiplicazione (ovvero la composizione di due valori a 32 bit in uno a 64 bit) è un problema per un programmatore, forse è meglio che si dedichi ad altro (in maniera analoga, non è certo per questo che un OS può essere migliore di un altro ...). |
||
![]() |
![]() |
![]() |
#37 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Comunque, Sam, ti conviene impacchettare tutto quanto in una bella shared library(.so/.dll).
Io mi sono creato le mie con una versione iterativa della funzione getDirInfo in modo da essere sicuro di non esaurire lo stack di sistema. Può capitare, con la versione ricorsiva, se il livello di annidamento delle sottodirectory è alto(p. es. con la directory root). La versione iterativa è pure più efficiente dal punto di vista delle prestazioni, è molto più veloce. ![]() |
![]() |
![]() |
![]() |
#38 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
Ah, Sam, ricordati di compilare col flag -D _FILE_OFFSET_BITS=64 quando compili a 32 bit:
Codice:
//getDirInfo(argv[1], &dim, 0, OnChange); getDirInfo(argv[1], &dim, 0, NULL); ![]() ![]() Usare il flag _FILE_OFFSET_BITS=64, anziché la funzione readdir64_r, rende il codice portabile. ![]() Ultima modifica di Vincenzo1968 : 11-03-2013 alle 18:44. |
![]() |
![]() |
![]() |
#39 |
Bannato
Iscritto dal: Mar 2008
Città: Villabate(PA)
Messaggi: 2515
|
|
![]() |
![]() |
![]() |
#40 | |
Member
Iscritto dal: Jan 2013
Messaggi: 205
|
Quote:
![]() |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 11:42.