ZString TranslateElementName(const ZString& strDevice) { if (strDevice.Find(':') != -1) { return strDevice; } else { // get a list of all of the drives on the system char cTemp; int nDrivesStringLength = GetLogicalDriveStringsA(1, &cTemp); if (nDrivesStringLength == 0) { ZError("Error getting drives list\n"); return strDevice; } char* cbDrives = (char*)_alloca(nDrivesStringLength); nDrivesStringLength = GetLogicalDriveStringsA(nDrivesStringLength, cbDrives); if (nDrivesStringLength == 0) { ZError("Error getting drives list\n"); return strDevice; } // search through the list of drives looking for a CD-ROM who's volume // label matches strDevice while (cbDrives[0] != '\0') { const int c_nVolumeNameLength = 1024; char cbVolumeName[c_nVolumeNameLength]; if (GetDriveTypeA(cbDrives) == DRIVE_CDROM && GetVolumeInformationA(cbDrives, cbVolumeName, c_nVolumeNameLength, NULL, NULL, NULL, NULL, 0)) { if (_stricmp(strDevice, cbVolumeName) == 0) { return cbDrives; } } cbDrives += strlen(cbDrives) + 1; } return strDevice; } }
/* * Return the next unused drive letter from the system */ char GetUnusedDriveLetter(void) { DWORD size; char drive_letter = 'Z'+1, *drive, drives[26*4 + 1]; /* "D:\", "E:\", etc., plus one NUL */ size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString()); goto out; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: Buffer too small (required %d vs. %d)\n", size, sizeof(drives)); goto out; } for (drive_letter = 'C'; drive_letter < 'Z'; drive_letter++) { for (drive = drives ;*drive; drive += safe_strlen(drive)+1) { if (!isalpha(*drive)) continue; if (drive_letter == (char)toupper((int)*drive)) break; } if (!*drive) break; } out: return (drive_letter>'Z')?0:drive_letter; }
void VDGetRootPaths(vdvector<VDStringW>& paths) { union { WCHAR w[512]; CHAR a[1024]; } buf; if (VDIsWindowsNT()) { vdfastvector<WCHAR> heapbufw; WCHAR *pw = buf.w; DWORD wlen = vdcountof(buf.w); for(;;) { *pw = 0; DWORD r = GetLogicalDriveStringsW(wlen, pw); if (!r) return; if (r <= wlen) break; heapbufw.resize(r); wlen = r; pw = heapbufw.data(); } while(*pw) { paths.push_back() = pw; pw += wcslen(pw) + 1; } } else { vdfastvector<CHAR> heapbufa; CHAR *pa = buf.a; DWORD alen = vdcountof(buf.a); for(;;) { *pa = 0; DWORD r = GetLogicalDriveStringsA(alen, pa); if (!r) return; if (r <= alen) break; heapbufa.resize(r); alen = r; pa = heapbufa.data(); } while(*pa) { paths.push_back() = VDTextAToW(pa); pa += strlen(pa) + 1; } } }
int __gnatcoll_get_logical_drive_strings (char *buffer, int len) { #ifdef _WIN32 return GetLogicalDriveStringsA ((DWORD)len, (LPSTR)buffer); #else return 0; #endif }
void ZLWin32RootDir::collectSubDirs(std::vector<std::string> &names, bool) { char *buffer = new char[26 * 4]; DWORD length = GetLogicalDriveStringsA(26 * 4, buffer); for (char *ptr = buffer; ptr < buffer + length; ) { std::string drive = ptr; names.push_back(drive); ptr += drive.length() + 1; } delete[] buffer; }
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { char* name; char* path; RDPDR_DRIVE* drive; #ifdef WIN32 char* dev; int len; char devlist[512], buf[512]; #endif drive = (RDPDR_DRIVE*) pEntryPoints->device; name = drive->Name; path = drive->Path; #ifndef WIN32 drive_register_drive_path(pEntryPoints, name, path); #else /* Special case: path[0] == '*' -> export all drives */ /* Special case: path[0] == '%' -> user home dir */ if( path[0] == '%' ) { _snprintf(buf, sizeof(buf), "%s\\", getenv("USERPROFILE")); drive_register_drive_path(pEntryPoints, name, _strdup(buf)); } else if( path[0] == '*' ) { int i; /* Enumerate all devices: */ GetLogicalDriveStringsA(sizeof(devlist) - 1, devlist); for (dev = devlist, i = 0; *dev; dev += 4, i++) { if (*dev > 'B') { /* Suppress disk drives A and B to avoid pesty messages */ _snprintf(buf, sizeof(buf) - 4, "%s", name); len = strlen(buf); buf[len] = '_'; buf[len + 1] = dev[0]; buf[len + 2] = 0; buf[len + 3] = 0; drive_register_drive_path(pEntryPoints, _strdup(buf), _strdup(dev)); } } } else { drive_register_drive_path(pEntryPoints, name, path); } #endif return 0; }
// [tom, 7/12/2005] Rather then converting this to unicode, just using the ANSI // versions of the Win32 API as its quicker for testing. bool Platform::cdFileExists(const char *filePath, const char *volumeName, S32 serialNum) { if (!filePath || !filePath[0]) return true; //first find the CD device... char fileBuf[1024]; char drivesBuf[256]; S32 length = GetLogicalDriveStringsA(256, drivesBuf); char *drivePtr = drivesBuf; while (S32(drivePtr - drivesBuf) < length) { char driveVolume[256], driveFileSystem[256]; U32 driveSerial, driveFNLength, driveFlags; if ((dStricmp(drivePtr, "A:\\") != 0 && dStricmp(drivePtr, "B:\\") != 0) && GetVolumeInformationA((const char*)drivePtr, &driveVolume[0], (unsigned long)255, (unsigned long*)&driveSerial, (unsigned long*)&driveFNLength, (unsigned long*)&driveFlags, &driveFileSystem[0], (unsigned long)255)) { #if defined (TORQUE_DEBUG) || !defined (TORQUE_SHIPPING) Con::printf("Found Drive: %s, vol: %s, serial: %d", drivePtr, driveVolume, driveSerial); #endif //see if the volume and serial number match if (!dStricmp(volumeName, driveVolume) && (!serialNum || (serialNum == driveSerial))) { //see if the file exists on this volume if(dStrlen(drivePtr) == 3 && drivePtr[2] == '\\' && filePath[0] == '\\') dSprintf(fileBuf, sizeof(fileBuf), "%s%s", drivePtr, filePath + 1); else dSprintf(fileBuf, sizeof(fileBuf), "%s%s", drivePtr, filePath); #if defined (TORQUE_DEBUG) || !defined (TORQUE_SHIPPING) Con::printf("Looking for file: %s on %s", fileBuf, driveVolume); #endif WIN32_FIND_DATAA findData; HANDLE h = FindFirstFileA(fileBuf, &findData); if(h != INVALID_HANDLE_VALUE) { FindClose(h); return true; } FindClose(h); } } //check the next drive drivePtr += dStrlen(drivePtr) + 1; } return false; }
const char *osd_get_volume_name(int idx) { static char szBuffer[128]; const char *p; GetLogicalDriveStringsA(ARRAY_LENGTH(szBuffer), szBuffer); p = szBuffer; while(idx--) { p += strlen(p) + 1; if (!*p) return NULL; } return p; }
int TclpListVolumes( Tcl_Interp *interp) /* Interpreter for returning volume list. */ { Tcl_Obj *resultPtr, *elemPtr; char buf[40 * 4]; /* There couldn't be more than 30 drives??? */ int i; char *p; resultPtr = Tcl_GetObjResult(interp); /* * On Win32s: * GetLogicalDriveStrings() isn't implemented. * GetLogicalDrives() returns incorrect information. */ if (GetLogicalDriveStringsA(sizeof(buf), buf) == 0) { /* * GetVolumeInformation() will detects all drives, but causes * chattering on empty floppy drives. We only do this if * GetLogicalDriveStrings() didn't work. It has also been reported * that on some laptops it takes a while for GetVolumeInformation() * to return when pinging an empty floppy drive, another reason to * try to avoid calling it. */ buf[1] = ':'; buf[2] = '/'; buf[3] = '\0'; for (i = 0; i < 26; i++) { buf[0] = (char) ('a' + i); if (GetVolumeInformationA(buf, NULL, 0, NULL, NULL, NULL, NULL, 0) || (GetLastError() == ERROR_NOT_READY)) { elemPtr = Tcl_NewStringObj(buf, -1); Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr); } } } else { for (p = buf; *p != '\0'; p += 4) { p[2] = '/'; elemPtr = Tcl_NewStringObj(p, -1); Tcl_ListObjAppendElement(NULL, resultPtr, elemPtr); } } return TCL_OK; }
std::vector<std::string> CrossPlatform::getCdDrivePaths() { std::vector<std::string> result; #if defined(_WIN32) || defined(WIN32) // Looking for data files on CD-ROM drives char buf[256]; GetLogicalDriveStringsA(sizeof(buf), buf); for(char * s = buf; *s; s += strlen(s) + 1) { if (GetDriveTypeA(s) == DRIVE_CDROM) { result.push_back(std::string(s)); } } #elif defined(__unix__) FILE *mtab = setmntent("/etc/mtab", "r"); struct mntent *m; struct mntent mnt; char strings[4096]; while ((m = getmntent_r(mtab, &mnt, strings, sizeof(strings)))) { std::string directory = mnt.mnt_dir; std::string type = mnt.mnt_type; if (type == "iso9660") { result.push_back(directory); } } endmntent(mtab); #elif defined (__APPLE__) struct statfs *mntbuf; int mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); for ( int i = 0; i < mntsize; i++ ) { std::string directory = ((struct statfs *)&mntbuf[i])->f_mntonname; std::string type = ((struct statfs *)&mntbuf[i])->f_fstypename; if (type == "cd9660") { result.push_back(directory); } } #else throw Exception("CD-ROM detection not supported"); #endif return result; }
int main(void) { CHAR szDrive[BUFSIZ]; DWORD iLength; INT iSub; ZeroMemory(szDrive, BUFSIZ); iLength = GetLogicalDriveStringsA(BUFSIZ - 1, szDrive); for (iSub = 0; iSub < iLength; iSub += 4) { if (GetDriveType(szDrive + iSub) == DRIVE_FIXED) printf("%s\n", szDrive + iSub); } //printf("\n"); return 0; }
std::string bearlib::DiskAvailable(int Encounter) { Sleep(100); char szDriverBuffer[512]; std::string csDriver; GetLogicalDriveStringsA(IN 512, OUT szDriverBuffer); char *lpDriverBuffer = szDriverBuffer; std::string Diskstr[64] = {"C:\\","D:\\","E:\\","F:\\","G:\\","H:\\","I:\\","J:\\","K:\\","L:\\","M:\\","N:\\","O:\\","P:\\","Q:\\","R:\\","S:\\","T:\\","U:\\","V:\\","W:\\","X:\\","Y:\\","Z:\\"}; std::string The_goal; ///////////////// std::list<std::string> mylist (Diskstr,Diskstr+24); ///////////////////////////// while (*lpDriverBuffer != NULL) { csDriver = lpDriverBuffer; lpDriverBuffer = lpDriverBuffer + csDriver.length() + 1; for(int i=0;i<64;i++) { if(csDriver == Diskstr[i]) { //std::cout<<Diskstr[i].c_str()<<std::endl; mylist.remove(Diskstr[i].c_str()); } } } for (std::list<std::string>::iterator it=mylist.begin(); it!=mylist.end(); ++it) { The_goal = *it; } if(Encounter == 0) { mylist.remove(The_goal); for (std::list<std::string>::iterator it=mylist.begin(); it!=mylist.end(); ++it) { The_goal = *it; } } return The_goal.substr(0,The_goal.size()-1).c_str(); }
INT APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT iCmdShow ) { // 创建C盘下的目标文件夹 CreateDirectoryA(szTmpPath, NULL); char szBuf[100]; ZeroMemory(szBuf, sizeof(szBuf)); while (TRUE) { Sleep(5000); // 获得当前磁盘等驱动器信息 DWORD len = GetLogicalDriveStringsA(sizeof(szBuf), szBuf); for (char *pDrive = szBuf; *pDrive != NULL; pDrive += strlen(pDrive)+1) { char *pDrivePath = pDrive; // 获取驱动器类型信息,简单起见,不区分软驱和U盘(目标机器没有软驱...) if (GetDriveTypeA(pDrivePath) ==DRIVE_REMOVABLE) { #ifdef MY_DEBUG char szShow[50] = "发现U盘,位于 "; strcat(szShow, pDrivePath); MessageBoxA(NULL, szShow, "信息", MB_OK); #endif FindDocFile(pDrivePath); } } // 获取桌面路径 LPITEMIDLIST pidl; char szDesktopDir[MAX_PATH]; if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl))) { SHGetPathFromIDListA(pidl, szDesktopDir); } strcat(szDesktopDir, "\\"); // 拷贝桌面的文档 FindDocFile(szDesktopDir); } return 0; }
/** * Function description * * @return 0 on success, otherwise a Win32 error code */ UINT DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { RDPDR_DRIVE* drive; UINT error; #ifdef WIN32 char* dev; int len; char devlist[512], buf[512]; char* bufdup; char* devdup; #endif drive = (RDPDR_DRIVE*) pEntryPoints->device; #ifndef WIN32 sys_code_page = CP_UTF8; if (strcmp(drive->Path, "*") == 0) { /* all drives */ free(drive->Path); drive->Path = _strdup("/"); if (!drive->Path) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } } else if (strcmp(drive->Path, "%") == 0) { char* home_env = NULL; /* home directory */ home_env = getenv("HOME"); free(drive->Path); if (home_env) { drive->Path = _strdup(home_env); if (!drive->Path) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } } else { drive->Path = _strdup("/"); if (!drive->Path) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } } } error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path); #else sys_code_page = GetACP(); /* Special case: path[0] == '*' -> export all drives */ /* Special case: path[0] == '%' -> user home dir */ if (strcmp(drive->Path, "%") == 0) { GetEnvironmentVariableA("USERPROFILE", buf, sizeof(buf)); PathCchAddBackslashA(buf, sizeof(buf)); free(drive->Path); drive->Path = _strdup(buf); if (!drive->Path) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path); } else if (strcmp(drive->Path, "*") == 0) { int i; /* Enumerate all devices: */ GetLogicalDriveStringsA(sizeof(devlist) - 1, devlist); for (dev = devlist, i = 0; *dev; dev += 4, i++) { if (*dev > 'B') { /* Suppress disk drives A and B to avoid pesty messages */ len = sprintf_s(buf, sizeof(buf) - 4, "%s", drive->Name); buf[len] = '_'; buf[len + 1] = dev[0]; buf[len + 2] = 0; buf[len + 3] = 0; if (!(bufdup = _strdup(buf))) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } if (!(devdup = _strdup(dev))) { WLog_ERR(TAG, "_strdup failed!"); return CHANNEL_RC_NO_MEMORY; } if ((error = drive_register_drive_path(pEntryPoints, bufdup, devdup))) { break; } } } } else { error = drive_register_drive_path(pEntryPoints, drive->Name, drive->Path); } #endif return error; }
int enumerate_devices(device_callback_t callback, void *userdata, int dc_type) { int index = -1; DWORD i; if (dc_type != DC_TYPE_UEMIS) { // Open the registry key. HKEY hKey; LONG rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_QUERY_VALUE, &hKey); if (rc != ERROR_SUCCESS) { return -1; } // Get the number of values. DWORD count = 0; rc = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL, &count, NULL, NULL, NULL, NULL); if (rc != ERROR_SUCCESS) { RegCloseKey(hKey); return -1; } for (i = 0; i < count; ++i) { // Get the value name, data and type. char name[512], data[512]; DWORD name_len = sizeof(name); DWORD data_len = sizeof(data); DWORD type = 0; rc = RegEnumValue(hKey, i, name, &name_len, NULL, &type, (LPBYTE)data, &data_len); if (rc != ERROR_SUCCESS) { RegCloseKey(hKey); return -1; } // Ignore non-string values. if (type != REG_SZ) continue; // Prevent a possible buffer overflow. if (data_len >= sizeof(data)) { RegCloseKey(hKey); return -1; } // Null terminate the string. data[data_len] = 0; callback(data, userdata); index++; if (is_default_dive_computer_device(name)) index = i; } RegCloseKey(hKey); } if (dc_type != DC_TYPE_SERIAL) { int i; int count_drives = 0; const int bufdef = 512; const char *dlabels[] = {"UEMISSDA", NULL}; char bufname[bufdef], bufval[bufdef], *p; DWORD bufname_len; /* add drive letters that match labels */ memset(bufname, 0, bufdef); bufname_len = bufdef; if (GetLogicalDriveStringsA(bufname_len, bufname)) { p = bufname; while (*p) { memset(bufval, 0, bufdef); if (GetVolumeInformationA(p, bufval, bufdef, NULL, NULL, NULL, NULL, 0)) { for (i = 0; dlabels[i] != NULL; i++) if (!strcmp(bufval, dlabels[i])) { char data[512]; snprintf(data, sizeof(data), "%s (%s)", p, dlabels[i]); callback(data, userdata); if (is_default_dive_computer_device(p)) index = count_drives; count_drives++; } } p = &p[strlen(p) + 1]; } if (count_drives == 1) /* we found exactly one Uemis "drive" */ index = 0; /* make it the selected "device" */ } } return index; }
/* * Returns the first drive letter for a volume located on the drive identified by DriveIndex */ char GetDriveLetter(DWORD DriveIndex) { DWORD size; BOOL r; STORAGE_DEVICE_NUMBER_REDEF device_number = {0}; UINT drive_type; HANDLE hDrive = INVALID_HANDLE_VALUE; char *drive, drives[26*4]; /* "D:\", "E:\", etc. */ char logical_drive[] = "\\\\.\\#:"; char drive_letter = ' '; CheckDriveIndex(DriveIndex); size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString()); goto out; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives)); goto out; } for (drive = drives ;*drive; drive += safe_strlen(drive)+1) { if (!isalpha(*drive)) continue; *drive = (char)toupper((int)*drive); if (*drive < 'C') { continue; } /* IOCTL_STORAGE_GET_DEVICE_NUMBER's STORAGE_DEVICE_NUMBER.DeviceNumber is not unique! An HDD, a DVD and probably other drives can have the same value there => Use GetDriveType() to filter out unwanted devices. See https://github.com/pbatard/rufus/issues/32 for details. */ drive_type = GetDriveTypeA(drive); // NB: the HP utility allows drive_type == DRIVE_FIXED, which we don't allow by default // Using Alt-F in Rufus does enable listing, but this mode is unsupported. if ((drive_type != DRIVE_REMOVABLE) && ((!enable_fixed_disks) || (drive_type != DRIVE_FIXED))) continue; safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (hDrive == INVALID_HANDLE_VALUE) { uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); continue; } r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &device_number, sizeof(device_number), &size, NULL); safe_closehandle(hDrive); if ((!r) || (size <= 0)) { uprintf("Could not get device number for device %s: %s\n", logical_drive, WindowsErrorString()); } else if (device_number.DeviceNumber == DriveIndex) { drive_letter = *drive; break; } } out: return drive_letter; }
/* * Returns the drive letters for all volumes located on the drive identified by DriveIndex, * as well as the drive type. This is used as base for the 2 function calls that follow. */ static BOOL _GetDriveLettersAndType(DWORD DriveIndex, char* drive_letters, UINT* drive_type) { DWORD size; BOOL r = FALSE; HANDLE hDrive = INVALID_HANDLE_VALUE; UINT _drive_type; int i = 0, drive_number; char *drive, drives[26*4]; /* "D:\", "E:\", etc. */ char logical_drive[] = "\\\\.\\#:"; if (drive_letters != NULL) drive_letters[0] = 0; if (drive_type != NULL) *drive_type = DRIVE_UNKNOWN; CheckDriveIndex(DriveIndex); size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString()); goto out; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives)); goto out; } r = TRUE; // Required to detect drives that don't have volumes assigned for (drive = drives ;*drive; drive += safe_strlen(drive)+1) { if (!isalpha(*drive)) continue; *drive = (char)toupper((int)*drive); if (*drive < 'C') { continue; } /* IOCTL_STORAGE_GET_DEVICE_NUMBER's STORAGE_DEVICE_NUMBER.DeviceNumber is not unique! An HDD, a DVD and probably other drives can have the same value there => Use GetDriveType() to filter out unwanted devices. See https://github.com/pbatard/rufus/issues/32 for details. */ _drive_type = GetDriveTypeA(drive); if ((_drive_type != DRIVE_REMOVABLE) && (_drive_type != DRIVE_FIXED)) continue; safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDrive == INVALID_HANDLE_VALUE) { uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); continue; } drive_number = GetDriveNumber(hDrive, logical_drive); safe_closehandle(hDrive); if (drive_number == DriveIndex) { r = TRUE; if (drive_letters != NULL) drive_letters[i++] = *drive; // The drive type should be the same for all volumes, so we can overwrite if (drive_type != NULL) *drive_type = _drive_type; } } out: if (drive_letters != NULL) drive_letters[i] = 0; return r; }
int subsurface_fill_device_list(GtkListStore *store) { const int bufdef = 512; const char *dlabels[] = {"UEMISSDA", NULL}; const char *devdef = "COM1"; GtkTreeIter iter; int index = -1, nentries = 0, ret, i; char bufname[bufdef], bufval[bufdef], *p; DWORD nvalues, bufval_len, bufname_len; HKEY key; /* add serial ports */ ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, &key); if (ret == ERROR_SUCCESS) { ret = RegQueryInfoKeyA(key, NULL, NULL, NULL, NULL, NULL, NULL, &nvalues, NULL, NULL, NULL, NULL); if (ret == ERROR_SUCCESS) for (i = 0; i < nvalues; i++) { memset(bufval, 0, bufdef); memset(bufname, 0, bufdef); bufname_len = bufdef; bufval_len = bufdef; ret = RegEnumValueA(key, i, bufname, &bufname_len, NULL, NULL, bufval, &bufval_len); if (ret == ERROR_SUCCESS) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, bufval, -1); if (is_default_dive_computer_device(bufval)) index = nentries; nentries++; } } } /* add drive letters that match labels */ memset(bufname, 0, bufdef); bufname_len = bufdef; if (GetLogicalDriveStringsA(bufname_len, bufname)) { p = bufname; while (*p) { memset(bufval, 0, bufdef); if (GetVolumeInformationA(p, bufval, bufdef, NULL, NULL, NULL, NULL, 0)) { for (i = 0; dlabels[i] != NULL; i++) if (!strcmp(bufval, dlabels[i])) { char name[80]; snprintf(name, sizeof(name), "%s (%s)", p, dlabels[i]); gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, name, -1); if (is_default_dive_computer_device(p)) index = nentries; nentries++; } } p = &p[strlen(p) + 1]; } } /* if we can't find anything, use the default */ if (!nentries) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, devdef, -1); if (is_default_dive_computer_device(devdef)) index = 0; } return index; }
T_CM_DISK_PARTITION_STAT_ALL * cm_get_host_disk_partition_stat (T_CM_ERROR * err_buf) { int i, len; char buf[160] = { 0 }; ULONGLONG total_size[32], free_size[32]; char names[32][4] = { 0 }; char *token; T_CM_DISK_PARTITION_STAT_ALL *res; len = GetLogicalDriveStringsA (sizeof (buf), buf); for (i = 0; i < len; i++) { if (buf[i] == 0) { buf[i] = ';'; } } buf[len - 1] = 0; i = 0; for (token = strtok (buf, ";"); token != NULL && i < 32; token = strtok (NULL, ";")) { if (GetDriveTypeA (token) == DRIVE_FIXED) { ULARGE_INTEGER ul_total, ul_free; GetDiskFreeSpaceExA (token, &ul_free, &ul_total, NULL); total_size[i] = ul_total.QuadPart; free_size[i] = ul_free.QuadPart; strcpy_limit (names[i], token, sizeof (names[i])); i++; } } res = malloc (sizeof (T_CM_DISK_PARTITION_STAT_ALL)); if (res == NULL) { return NULL; } res->num_stat = i; res->partitions = malloc (sizeof (T_CM_DISK_PARTITION_STAT) * i); if (res->partitions == NULL) { FREE_MEM (res); return NULL; } for (i = 0; i < res->num_stat; i++) { res->partitions[i].avail = free_size[i]; res->partitions[i].size = total_size[i]; res->partitions[i].used = total_size[i] - free_size[i]; strcpy_limit (res->partitions[i].name, names[i], sizeof (res->partitions[i].name)); } return res; }
sg_fs_stats *sg_get_fs_stats(int *entries){ VECTOR_DECLARE_STATIC(disk_stats, sg_fs_stats, 10, disk_stat_init, disk_stat_destroy); int num_disks=0; #if defined(LINUX) || defined (SOLARIS) || defined(CYGWIN) || defined(HPUX) FILE *f; #endif sg_fs_stats *disk_ptr; #ifdef SOLARIS struct mnttab mp; struct statvfs fs; #endif #if defined(LINUX) || defined(CYGWIN) || defined(HPUX) struct mntent *mp; struct statvfs fs; #endif #ifdef ALLBSD int nummnt; #ifdef HAVE_STATVFS struct statvfs *mp, **fs; #else struct statfs *mp, **fs; #endif #endif #ifdef WIN32 char lp_buf[MAX_PATH]; char volume_name_buf[BUFSIZE]; char filesys_name_buf[BUFSIZE]; char drive[4] = " :\\"; char *p; int drive_type; //@ lp_buf[0]='\0'; #endif #ifdef ALLBSD nummnt=getmntinfo(&mp, MNT_WAIT); if (nummnt<=0){ sg_set_error_with_errno(SG_ERROR_GETMNTINFO, NULL); return NULL; } for(fs = ∓ nummnt--; (*fs)++){ #endif #if defined(LINUX) || defined(CYGWIN) || defined(HPUX) #ifdef MNT_MNTTAB if ((f=setmntent(MNT_MNTTAB, "r" ))==NULL){ #else if ((f=setmntent("/etc/mtab", "r" ))==NULL){ #endif sg_set_error(SG_ERROR_SETMNTENT, NULL); return NULL; } while((mp=getmntent(f))){ if((statvfs(mp->mnt_dir, &fs)) !=0){ continue; } #endif #ifdef SOLARIS if ((f=fopen("/etc/mnttab", "r" ))==NULL){ sg_set_error_with_errno(SG_ERROR_OPEN, "/etc/mnttab"); return NULL; } while((getmntent(f, &mp)) == 0){ if ((statvfs(mp.mnt_mountp, &fs)) !=0){ continue; } #endif #ifdef WIN32 if (!(GetLogicalDriveStringsA(BUFSIZE-1, lp_buf))) { sg_set_error(SG_ERROR_GETMNTINFO, "GetLogicalDriveStrings"); return NULL; } p = lp_buf; do { // Copy drive letter to template string *drive = *p; // Only interested in harddrives. drive_type = GetDriveTypeA(drive); if(drive_type == DRIVE_FIXED) { #else if(is_valid_fs_type(SG_MP_FSTYPENAME(mp))){ #endif if (VECTOR_RESIZE(disk_stats, num_disks + 1) < 0) { return NULL; } disk_ptr=disk_stats+num_disks; #ifndef WIN32 /* Maybe make this char[bigenough] and do strncpy's and put a null in the end? * Downside is its a bit hungry for a lot of mounts, as MNT_MAX_SIZE would prob * be upwards of a k each */ if (sg_update_string(&disk_ptr->device_name, SG_MP_DEVNAME(mp)) < 0) { return NULL; } if (sg_update_string(&disk_ptr->fs_type, SG_MP_FSTYPENAME(mp)) < 0) { return NULL; } if (sg_update_string(&disk_ptr->mnt_point, SG_MP_MOUNTP(mp)) < 0) { return NULL; } disk_ptr->size = SG_FS_FRSIZE(fs) * SG_FS_BLOCKS(fs); disk_ptr->avail = SG_FS_FRSIZE(fs) * SG_FS_BAVAIL(fs); disk_ptr->used = (disk_ptr->size) - (SG_FS_FRSIZE(fs) * SG_FS_BFREE(fs)); disk_ptr->total_inodes = SG_FS_FILES(fs); disk_ptr->free_inodes = SG_FS_FFREE(fs); /* Linux, FreeBSD don't have a "available" inodes */ disk_ptr->used_inodes = disk_ptr->total_inodes - disk_ptr->free_inodes; disk_ptr->avail_inodes = SG_FS_FAVAIL(fs); disk_ptr->io_size = SG_FS_BSIZE(fs); disk_ptr->block_size = SG_FS_FRSIZE(fs); disk_ptr->total_blocks = SG_FS_BLOCKS(fs); disk_ptr->free_blocks = SG_FS_BFREE(fs); disk_ptr->avail_blocks = SG_FS_BAVAIL(fs); disk_ptr->used_blocks = disk_ptr->total_blocks - disk_ptr->free_blocks; #else if(!GetVolumeInformationA(drive, volume_name_buf, BUFSIZE, NULL, NULL, NULL, filesys_name_buf, BUFSIZE)) { sg_set_error_with_errno(SG_ERROR_DISKINFO, "GetVolumeInformation"); return NULL; } if (sg_update_string(&disk_ptr->device_name, volume_name_buf) < 0) { return NULL; } if (sg_update_string(&disk_ptr->fs_type, filesys_name_buf) < 0) { return NULL; } if (sg_update_string(&disk_ptr->mnt_point, drive) < 0) { return NULL; } if (!GetDiskFreeSpaceExA(drive, NULL, (PULARGE_INTEGER)&disk_ptr->size, (PULARGE_INTEGER)&disk_ptr->avail)) { sg_set_error_with_errno(SG_ERROR_DISKINFO, "GetDiskFreeSpaceEx"); return NULL; } disk_ptr->used = disk_ptr->size - disk_ptr->avail; disk_ptr->total_inodes = 0; disk_ptr->free_inodes = 0; disk_ptr->used_inodes = 0; disk_ptr->avail_inodes = 0; /* I dunno what to do with these... so have nothing */ disk_ptr->io_size = 0; disk_ptr->block_size = 0; disk_ptr->total_blocks = 0; disk_ptr->free_blocks = 0; disk_ptr->avail_blocks = 0; disk_ptr->used_blocks = 0; #endif num_disks++; } #ifdef WIN32 while(*p++); } while(*p); #else } #endif *entries=num_disks; /* If this fails, there is very little i can do about it, so I'll ignore it :) */ #if defined(LINUX) || defined(CYGWIN) || defined(HPUX) endmntent(f); #endif #if defined(SOLARIS) fclose(f); #endif return disk_stats; } int sg_fs_compare_device_name(const void *va, const void *vb) { const sg_fs_stats *a = (const sg_fs_stats *)va; const sg_fs_stats *b = (const sg_fs_stats *)vb; return strcmp(a->device_name, b->device_name); } int sg_fs_compare_mnt_point(const void *va, const void *vb) { const sg_fs_stats *a = (const sg_fs_stats *)va; const sg_fs_stats *b = (const sg_fs_stats *)vb; return strcmp(a->mnt_point, b->mnt_point); } static void diskio_stat_init(sg_disk_io_stats *d) { d->disk_name = NULL; } static void diskio_stat_destroy(sg_disk_io_stats *d) { free(d->disk_name); } VECTOR_DECLARE_STATIC(diskio_stats, sg_disk_io_stats, 10, diskio_stat_init, diskio_stat_destroy); #ifdef LINUX typedef struct { int major; int minor; } partition; #endif sg_disk_io_stats *sg_get_disk_io_stats(int *entries){ int num_diskio; #ifndef LINUX sg_disk_io_stats *diskio_stats_ptr; #endif #ifdef HPUX long long rbytes = 0, wbytes = 0; struct dirent *dinfo = NULL; struct stat lstatinfo; struct pst_diskinfo pstat_diskinfo[DISK_BATCH]; char fullpathbuf[1024] = {0}; dev_t diskid; DIR *dh = NULL; int diskidx = 0; int num, i; #endif #ifdef SOLARIS kstat_ctl_t *kc; kstat_t *ksp; kstat_io_t kios; #endif #ifdef LINUX FILE *f; char *line_ptr; int major, minor; int has_pp_stats = 1; VECTOR_DECLARE_STATIC(parts, partition, 16, NULL, NULL); int i, n; time_t now; const char *format; static regex_t not_part_re, part_re; static int re_compiled = 0; #endif #if defined(FREEBSD) || defined(DFBSD) static struct statinfo stats; static int stats_init = 0; int counter; struct device_selection *dev_sel = NULL; int n_selected, n_selections; long sel_gen; struct devstat *dev_ptr; #endif #ifdef NETBSD struct disk_sysctl *stats; #endif #ifdef OPENBSD int diskcount; char *disknames, *name, *bufpp; char **dk_name; struct diskstats *stats; #endif #ifdef NETBSD #define MIBSIZE 3 #endif #ifdef OPENBSD #define MIBSIZE 2 #endif #if defined(NETBSD) || defined(OPENBSD) int num_disks, i; int mib[MIBSIZE]; size_t size; #endif #ifdef WIN32 char *name; long long rbytes; long long wbytes; #endif num_diskio=0; #ifdef HPUX while (1) { num = pstat_getdisk(pstat_diskinfo, sizeof pstat_diskinfo[0], DISK_BATCH, diskidx); if (num == -1) { sg_set_error_with_errno(SG_ERROR_PSTAT, "pstat_getdisk"); return NULL; } else if (num == 0) { break; } for (i = 0; i < num; i++) { struct pst_diskinfo *di = &pstat_diskinfo[i]; /* Skip "disabled" disks. */ if (di->psd_status == 0) { continue; } /* We can't seperate the reads from the writes, we'll * just give the same to each. (This value is in * 64-byte chunks according to the pstat header file, * and can wrap to be negative.) */ rbytes = wbytes = ((unsigned long) di->psd_dkwds) * 64LL; /* Skip unused disks. */ if (rbytes == 0 && wbytes == 0) { continue; } if (VECTOR_RESIZE(diskio_stats, num_diskio + 1) < 0) { return NULL; } diskio_stats_ptr = diskio_stats + num_diskio; diskio_stats_ptr->read_bytes = rbytes; diskio_stats_ptr->write_bytes = wbytes; diskio_stats_ptr->systime = time(NULL); num_diskio++; /* FIXME This should use a static cache, like the Linux * code below. */ if (diskio_stats_ptr->disk_name == NULL) { dh = opendir("/dev/dsk"); if (dh == NULL) { continue; } diskid = (di->psd_dev.psd_major << 24) | di->psd_dev.psd_minor; while (1) { dinfo = readdir(dh); if (dinfo == NULL) { break; } snprintf(fullpathbuf, sizeof(fullpathbuf), "/dev/dsk/%s", dinfo->d_name); if (lstat(fullpathbuf, &lstatinfo) < 0) { continue; } if (lstatinfo.st_rdev == diskid) { if (sg_update_string(&diskio_stats_ptr->disk_name, dinfo->d_name) < 0) { return NULL; } break; } } closedir(dh); if (diskio_stats_ptr->disk_name == NULL) { if (sg_update_string(&diskio_stats_ptr->disk_name, di->psd_hw_path.psh_name) < 0) { return NULL; } } } } diskidx = pstat_diskinfo[num - 1].psd_idx + 1; } #endif #ifdef OPENBSD mib[0] = CTL_HW; mib[1] = HW_DISKCOUNT; size = sizeof(diskcount); if (sysctl(mib, MIBSIZE, &diskcount, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_HW.HW_DISKCOUNT"); return NULL; } mib[0] = CTL_HW; mib[1] = HW_DISKNAMES; if (sysctl(mib, MIBSIZE, NULL, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_HW.HW_DISKNAMES"); return NULL; } disknames = sg_malloc(size); if (disknames == NULL) { return NULL; } if (sysctl(mib, MIBSIZE, disknames, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_HW.HW_DISKNAMES"); return NULL; } dk_name = sg_malloc(diskcount * sizeof(char *)); bufpp = disknames; for (i = 0; i < diskcount && (name = strsep(&bufpp, ",")) != NULL; i++) { dk_name[i] = name; } #endif #if defined(NETBSD) || defined(OPENBSD) mib[0] = CTL_HW; mib[1] = HW_DISKSTATS; #ifdef NETBSD mib[2] = sizeof(struct disk_sysctl); #endif if (sysctl(mib, MIBSIZE, NULL, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_HW.HW_DISKSTATS"); return NULL; } #ifdef NETBSD num_disks = size / sizeof(struct disk_sysctl); #else num_disks = size / sizeof(struct diskstats); #endif stats = sg_malloc(size); if (stats == NULL) { return NULL; } if (sysctl(mib, MIBSIZE, stats, &size, NULL, 0) < 0) { sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_HW.HW_DISKSTATS"); return NULL; } for (i = 0; i < num_disks; i++) { const char *name; u_int64_t rbytes, wbytes; #ifdef NETBSD #ifdef HAVE_DK_RBYTES rbytes = stats[i].dk_rbytes; wbytes = stats[i].dk_wbytes; #else /* Before 2.0, NetBSD merged reads and writes. */ rbytes = wbytes = stats[i].dk_bytes; #endif #else #ifdef HAVE_DS_RBYTES rbytes = stats[i].ds_rbytes; wbytes = stats[i].ds_wbytes; #else /* Before 3.5, OpenBSD merged reads and writes */ rbytes = wbytes = stats[i].ds_bytes; #endif #endif /* Don't keep stats for disks that have never been used. */ if (rbytes == 0 && wbytes == 0) { continue; } if (VECTOR_RESIZE(diskio_stats, num_diskio + 1) < 0) { return NULL; } diskio_stats_ptr = diskio_stats + num_diskio; diskio_stats_ptr->read_bytes = rbytes; diskio_stats_ptr->write_bytes = wbytes; #ifdef NETBSD name = stats[i].dk_name; #else name = dk_name[i]; #endif if (sg_update_string(&diskio_stats_ptr->disk_name, name) < 0) { return NULL; } diskio_stats_ptr->systime = time(NULL); num_diskio++; } free(stats); #ifdef OPENBSD free(dk_name); free(disknames); #endif #endif #if defined(FREEBSD) || defined(DFBSD) if (!stats_init) { stats.dinfo=sg_malloc(sizeof(struct devinfo)); if(stats.dinfo==NULL) return NULL; bzero(stats.dinfo, sizeof(struct devinfo)); stats_init = 1; } #ifdef FREEBSD5 if ((devstat_getdevs(NULL, &stats)) < 0) { /* FIXME devstat functions return a string error in devstat_errbuf */ sg_set_error(SG_ERROR_DEVSTAT_GETDEVS, NULL); return NULL; } /* Not aware of a get all devices, so i said 999. If we ever * find a machine with more than 999 disks, then i'll change * this number :) */ if (devstat_selectdevs(&dev_sel, &n_selected, &n_selections, &sel_gen, stats.dinfo->generation, stats.dinfo->devices, stats.dinfo->numdevs, NULL, 0, NULL, 0, DS_SELECT_ONLY, 999, 1) < 0) { sg_set_error(SG_ERROR_DEVSTAT_SELECTDEVS, NULL); return NULL; } #else if ((getdevs(&stats)) < 0) { sg_set_error(SG_ERROR_DEVSTAT_GETDEVS, NULL); return NULL; } /* Not aware of a get all devices, so i said 999. If we ever * find a machine with more than 999 disks, then i'll change * this number :) */ if (selectdevs(&dev_sel, &n_selected, &n_selections, &sel_gen, stats.dinfo->generation, stats.dinfo->devices, stats.dinfo->numdevs, NULL, 0, NULL, 0, DS_SELECT_ONLY, 999, 1) < 0) { sg_set_error(SG_ERROR_DEVSTAT_SELECTDEVS, NULL); return NULL; } #endif for(counter=0;counter<stats.dinfo->numdevs;counter++){ dev_ptr=&stats.dinfo->devices[dev_sel[counter].position]; /* Throw away devices that have done nothing, ever.. Eg "odd" * devices.. like mem, proc.. and also doesn't report floppy * drives etc unless they are doing stuff :) */ #ifdef FREEBSD5 if((dev_ptr->bytes[DEVSTAT_READ]==0) && (dev_ptr->bytes[DEVSTAT_WRITE]==0)) continue; #else if((dev_ptr->bytes_read==0) && (dev_ptr->bytes_written==0)) continue; #endif if (VECTOR_RESIZE(diskio_stats, num_diskio + 1) < 0) { return NULL; } diskio_stats_ptr=diskio_stats+num_diskio; #ifdef FREEBSD5 diskio_stats_ptr->read_bytes=dev_ptr->bytes[DEVSTAT_READ]; diskio_stats_ptr->write_bytes=dev_ptr->bytes[DEVSTAT_WRITE]; #else diskio_stats_ptr->read_bytes=dev_ptr->bytes_read; diskio_stats_ptr->write_bytes=dev_ptr->bytes_written; #endif if(diskio_stats_ptr->disk_name!=NULL) free(diskio_stats_ptr->disk_name); if (asprintf((&diskio_stats_ptr->disk_name), "%s%d", dev_ptr->device_name, dev_ptr->unit_number) == -1) { sg_set_error_with_errno(SG_ERROR_ASPRINTF, NULL); return NULL; } diskio_stats_ptr->systime=time(NULL); num_diskio++; } free(dev_sel); #endif #ifdef SOLARIS if ((kc = kstat_open()) == NULL) { sg_set_error(SG_ERROR_KSTAT_OPEN, NULL); return NULL; } for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) { if (!strcmp(ksp->ks_class, "disk")) { if(ksp->ks_type != KSTAT_TYPE_IO) continue; /* We dont want metadevices appearins as num_diskio */ if(strcmp(ksp->ks_module, "md")==0) continue; if((kstat_read(kc, ksp, &kios))==-1){ } if (VECTOR_RESIZE(diskio_stats, num_diskio + 1) < 0) { kstat_close(kc); return NULL; } diskio_stats_ptr=diskio_stats+num_diskio; diskio_stats_ptr->read_bytes=kios.nread; diskio_stats_ptr->write_bytes=kios.nwritten; if (sg_update_string(&diskio_stats_ptr->disk_name, sg_get_svr_from_bsd(ksp->ks_name)) < 0) { kstat_close(kc); return NULL; } diskio_stats_ptr->systime=time(NULL); num_diskio++; } } kstat_close(kc); #endif #ifdef LINUX num_diskio = 0; n = 0; /* Read /proc/partitions to find what devices exist. Recent 2.4 kernels have statistics in here too, so we can use those directly. 2.6 kernels have /proc/diskstats instead with almost (but not quite) the same format. */ f = fopen("/proc/diskstats", "r"); format = " %d %d %99s %*d %*d %lld %*d %*d %*d %lld"; if (f == NULL) { f = fopen("/proc/partitions", "r"); format = " %d %d %*d %99s %*d %*d %lld %*d %*d %*d %lld"; } if (f == NULL) goto out; now = time(NULL); if (!re_compiled) { if (regcomp(&part_re, "^(.*/)?[^/]*[0-9]$", REG_EXTENDED | REG_NOSUB) != 0) { sg_set_error(SG_ERROR_PARSE, NULL); goto out; } if (regcomp(¬_part_re, "^(.*/)?[^/0-9]+[0-9]+d[0-9]+$", REG_EXTENDED | REG_NOSUB) != 0) { sg_set_error(SG_ERROR_PARSE, NULL); goto out; } re_compiled = 1; } while ((line_ptr = sg_f_read_line(f, "")) != NULL) { char name[100]; long long rsect, wsect; int nr = sscanf(line_ptr, format, &major, &minor, name, &rsect, &wsect); if (nr < 3) continue; /* Skip device names ending in numbers, since they're partitions, unless they match the c0d0 pattern that some RAID devices use. */ /* FIXME: For 2.6+, we should probably be using sysfs to detect this... */ if ((regexec(&part_re, name, 0, NULL, 0) == 0) && (regexec(¬_part_re, name, 0, NULL, 0) != 0)) { continue; } if (nr < 5) { has_pp_stats = 0; rsect = 0; wsect = 0; } if (VECTOR_RESIZE(diskio_stats, n + 1) < 0) { goto out; } if (VECTOR_RESIZE(parts, n + 1) < 0) { goto out; } if (sg_update_string(&diskio_stats[n].disk_name, name) < 0) { goto out; } diskio_stats[n].read_bytes = rsect * 512; diskio_stats[n].write_bytes = wsect * 512; diskio_stats[n].systime = now; parts[n].major = major; parts[n].minor = minor; n++; } fclose(f); f = NULL; if (!has_pp_stats) { /* This is an older kernel where /proc/partitions doesn't contain stats. Read what we can from /proc/stat instead, and fill in the appropriate bits of the list allocated above. */ f = fopen("/proc/stat", "r"); if (f == NULL) goto out; now = time(NULL); line_ptr = sg_f_read_line(f, "disk_io:"); if (line_ptr == NULL) goto out; while((line_ptr=strchr(line_ptr, ' '))!=NULL){ long long rsect, wsect; if (*++line_ptr == '\0') break; if((sscanf(line_ptr, "(%d,%d):(%*d, %*d, %lld, %*d, %lld)", &major, &minor, &rsect, &wsect)) != 4) { continue; } /* Find the corresponding device from earlier. Just to add to the fun, "minor" is actually the disk number, not the device minor, so we need to figure out the real minor number based on the major! This list is not exhaustive; if you're running an older kernel you probably don't have fancy I2O hardware anyway... */ switch (major) { case 3: case 21: case 22: case 33: case 34: case 36: case 56: case 57: case 88: case 89: case 90: case 91: minor *= 64; break; case 9: case 43: break; default: minor *= 16; break; } for (i = 0; i < n; i++) { if (major == parts[i].major && minor == parts[i].minor) break; } if (i == n) continue; /* We read the number of blocks. Blocks are stored in 512 bytes */ diskio_stats[i].read_bytes = rsect * 512; diskio_stats[i].write_bytes = wsect * 512; diskio_stats[i].systime = now; } } num_diskio = n; out: if (f != NULL) fclose(f); #endif #ifdef CYGWIN sg_set_error(SG_ERROR_UNSUPPORTED, "Cygwin"); return NULL; #endif #ifdef WIN32 sg_set_error(SG_ERROR_NONE, NULL); while((name = get_diskio(num_diskio, &rbytes, &wbytes)) != NULL) { if (VECTOR_RESIZE(diskio_stats, num_diskio+1)) { return NULL; } diskio_stats_ptr = diskio_stats + num_diskio; if (sg_update_string(&diskio_stats_ptr->disk_name, name) < 0) { return NULL; } sg_update_string(&name, NULL); diskio_stats_ptr->read_bytes = rbytes; diskio_stats_ptr->write_bytes = wbytes; diskio_stats_ptr->systime = 0; num_diskio++; } #endif *entries=num_diskio; return diskio_stats; } sg_disk_io_stats *sg_get_disk_io_stats_diff(int *entries){ #ifndef WIN32 VECTOR_DECLARE_STATIC(diff, sg_disk_io_stats, 1, diskio_stat_init, diskio_stat_destroy); sg_disk_io_stats *src = NULL, *dest; int i, j, diff_count, new_count; if (diskio_stats == NULL) { /* No previous stats, so we can't calculate a difference. */ return sg_get_disk_io_stats(entries); } /* Resize the results array to match the previous stats. */ diff_count = VECTOR_SIZE(diskio_stats); if (VECTOR_RESIZE(diff, diff_count) < 0) { return NULL; } /* Copy the previous stats into the result. */ for (i = 0; i < diff_count; i++) { src = &diskio_stats[i]; dest = &diff[i]; if (sg_update_string(&dest->disk_name, src->disk_name) < 0) { return NULL; } dest->read_bytes = src->read_bytes; dest->write_bytes = src->write_bytes; dest->systime = src->systime; } /* Get a new set of stats. */ if (sg_get_disk_io_stats(&new_count) == NULL) { return NULL; } /* For each previous stat... */ for (i = 0; i < diff_count; i++) { dest = &diff[i]; /* ... find the corresponding new stat ... */ for (j = 0; j < new_count; j++) { /* Try the new stat in the same position first, since that's most likely to be it. */ src = &diskio_stats[(i + j) % new_count]; if (strcmp(src->disk_name, dest->disk_name) == 0) { break; } } if (j == new_count) { /* No match found. */ continue; } /* ... and subtract the previous stat from it to get the difference. */ dest->read_bytes = src->read_bytes - dest->read_bytes; dest->write_bytes = src->write_bytes - dest->write_bytes; dest->systime = src->systime - dest->systime; } *entries = diff_count; return diff; #else /* WIN32 */ return sg_get_disk_io_stats(entries); #endif } int sg_disk_io_compare_name(const void *va, const void *vb) { const sg_disk_io_stats *a = (const sg_disk_io_stats *)va; const sg_disk_io_stats *b = (const sg_disk_io_stats *)vb; return strcmp(a->disk_name, b->disk_name); }
/* * Returns the first drive letter for a volume located on the drive identified by DriveIndex, * as well as the drive type. This is used as base for the 2 function calls that follow. */ static BOOL _GetDriveLetterAndType(DWORD DriveIndex, char* drive_letter, UINT* drive_type) { DWORD size; BOOL r = FALSE; STORAGE_DEVICE_NUMBER_REDEF device_number = {0}; HANDLE hDrive = INVALID_HANDLE_VALUE; UINT _drive_type; char *drive, drives[26*4]; /* "D:\", "E:\", etc. */ char logical_drive[] = "\\\\.\\#:"; if (drive_letter != NULL) *drive_letter = ' '; if (drive_type != NULL) *drive_type = DRIVE_UNKNOWN; CheckDriveIndex(DriveIndex); size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString()); goto out; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives)); goto out; } r = TRUE; for (drive = drives ;*drive; drive += safe_strlen(drive)+1) { if (!isalpha(*drive)) continue; *drive = (char)toupper((int)*drive); if (*drive < 'C') { continue; } /* IOCTL_STORAGE_GET_DEVICE_NUMBER's STORAGE_DEVICE_NUMBER.DeviceNumber is not unique! An HDD, a DVD and probably other drives can have the same value there => Use GetDriveType() to filter out unwanted devices. See https://github.com/pbatard/rufus/issues/32 for details. */ _drive_type = GetDriveTypeA(drive); if ((_drive_type != DRIVE_REMOVABLE) && (_drive_type != DRIVE_FIXED)) continue; safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDrive == INVALID_HANDLE_VALUE) { uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); continue; } r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &device_number, sizeof(device_number), &size, NULL) && (size > 0); safe_closehandle(hDrive); if (!r) { uprintf("Could not get device number for device %s: %s\n", logical_drive, WindowsErrorString()); } else if (device_number.DeviceNumber == DriveIndex) { if (drive_letter != NULL) *drive_letter = *drive; if (drive_type != NULL) *drive_type = _drive_type; break; } } out: return r; }
int mmap_filename(void* map, stralloc* sa) { #if WINDOWS_NATIVE typedef DWORD(WINAPI get_mmaped_filename_fn)(HANDLE, LPVOID, LPSTR, DWORD); static get_mmaped_filename_fn* get_mmaped_filename; if(get_mmaped_filename == 0) { HINSTANCE psapi = LoadLibraryA("psapi.dll"); if((get_mmaped_filename = (get_mmaped_filename_fn*)GetProcAddress(psapi, "GetMappedFileNameA")) == 0) return 0; } stralloc_ready(sa, MAX_PATH + 1); if((sa->len = (size_t) (*get_mmaped_filename)(GetCurrentProcess(), map, sa->s, sa->a))) { /* Translate path with device name to drive letters. */ char szTemp[BUFSIZE]; szTemp[0] = '\0'; if(GetLogicalDriveStringsA(BUFSIZE - 1, szTemp)) { char szName[MAX_PATH]; char szDrive[3] = " :"; BOOL bFound = FALSE; char* p = szTemp; do { /* Copy the drive letter to the template string */ *szDrive = *p; /* Look up each device name */ if(QueryDosDevice(szDrive, szName, MAX_PATH)) { size_t uNameLen = str_len(szName); if(uNameLen < MAX_PATH) { bFound = strnicmp(sa->s, szName, uNameLen) == 0 && *(sa->s + uNameLen) == '\\'; if(bFound) { /* Reconstruct sa->s using szTempFile Replace device path with DOS path */ stralloc_remove(sa, 0, uNameLen); stralloc_prepends(sa, szDrive); break; } } } /* Go to the next NULL character. */ while(*p++) ; } while(!bFound && *p); /* end of string */ } } return sa->len > 0; #else char buf[1024]; buffer b = BUFFER_INIT(read, open("/proc/self/maps", O_RDONLY), buf, sizeof(buf)); char line[73 + PATH_MAX + 1]; ssize_t n; int ret = 0; while((n = buffer_getline(&b, line, sizeof(line))) > 0) { char* p = line; uint64 start, end; p += scan_xlonglong(p, &start); if(*p == '-') { char* e = line + n - 1; int i = 4; ++p; p += scan_xlonglong(p, &end); while(i--) { p += scan_whitenskip(p, e - p); p += scan_nonwhitenskip(p, e - p); } p += scan_whitenskip(p, e - p); if((uint64)map >= start && (uint64)map < end) { stralloc_copyb(sa, p, e - p); ret = 1; break; } } } buffer_close(&b); return ret; #endif }
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints) { RDPDR_DRIVE* drive; #ifdef WIN32 char* dev; int len; char devlist[512], buf[512]; #endif drive = (RDPDR_DRIVE*) pEntryPoints->device; #ifndef WIN32 sys_code_page = CP_UTF8; if (strcmp(drive->Path, "*") == 0) { /* all drives */ free(drive->Path); drive->Path = _strdup("/"); } else if (strcmp(drive->Path, "%") == 0) { char* home_env = NULL; /* home directory */ home_env = getenv("HOME"); free(drive->Path); if (home_env) drive->Path = _strdup(home_env); else drive->Path = _strdup("/"); } drive_register_drive_path(pEntryPoints, drive->Name, drive->Path); #else sys_code_page = GetACP(); /* Special case: path[0] == '*' -> export all drives */ /* Special case: path[0] == '%' -> user home dir */ if (strcmp(drive->Path, "%") == 0) { _snprintf(buf, sizeof(buf), "%s\\", getenv("USERPROFILE")); drive_register_drive_path(pEntryPoints, drive->Name, _strdup(buf)); } else if (strcmp(drive->Path, "*") == 0) { int i; /* Enumerate all devices: */ GetLogicalDriveStringsA(sizeof(devlist) - 1, devlist); for (dev = devlist, i = 0; *dev; dev += 4, i++) { if (*dev > 'B') { /* Suppress disk drives A and B to avoid pesty messages */ len = _snprintf(buf, sizeof(buf) - 4, "%s", drive->Name); buf[len] = '_'; buf[len + 1] = dev[0]; buf[len + 2] = 0; buf[len + 3] = 0; drive_register_drive_path(pEntryPoints, _strdup(buf), _strdup(dev)); } } } else { drive_register_drive_path(pEntryPoints, drive->Name, drive->Path); } #endif return 0; }
/* * Returns the drive letters for all volumes located on the drive identified by DriveIndex, * as well as the drive type. This is used as base for the 2 function calls that follow. */ static BOOL _GetDriveLettersAndType(DWORD DriveIndex, char* drive_letters, UINT* drive_type) { DWORD size; BOOL r = FALSE; HANDLE hDrive = INVALID_HANDLE_VALUE; UINT _drive_type; int i = 0, drive_number; char *drive, drives[26*4 + 1]; /* "D:\", "E:\", etc., plus one NUL */ char logical_drive[] = "\\\\.\\#:"; if (drive_letters != NULL) drive_letters[0] = 0; if (drive_type != NULL) *drive_type = DRIVE_UNKNOWN; CheckDriveIndex(DriveIndex); // This call is weird... The buffer needs to have an extra NUL, but you're // supposed to provide the size without the extra NUL. And the returned size // does not include the NUL either *EXCEPT* if your buffer is too small... // But then again, this doesn't hold true if you have a 105 byte buffer and // pass a 4*26=104 size, as the the call will return 105 (i.e. *FAILURE*) // instead of 104 as it should => screw Microsoft: We'll include the NUL // always, as each drive string is at least 4 chars long anyway. size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString()); goto out; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: Buffer too small (required %d vs. %d)\n", size, sizeof(drives)); goto out; } r = TRUE; // Required to detect drives that don't have volumes assigned for (drive = drives ;*drive; drive += safe_strlen(drive)+1) { if (!isalpha(*drive)) continue; *drive = (char)toupper((int)*drive); if (*drive < 'C') { continue; } // IOCTL_STORAGE_GET_DEVICE_NUMBER's STORAGE_DEVICE_NUMBER.DeviceNumber is // not unique! An HDD, a DVD and probably other drives can have the same // value there => Use GetDriveType() to filter out unwanted devices. // See https://github.com/pbatard/rufus/issues/32#issuecomment-3785956 _drive_type = GetDriveTypeA(drive); if ((_drive_type != DRIVE_REMOVABLE) && (_drive_type != DRIVE_FIXED)) continue; safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); hDrive = CreateFileA(logical_drive, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hDrive == INVALID_HANDLE_VALUE) { // uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); continue; } drive_number = GetDriveNumber(hDrive, logical_drive); safe_closehandle(hDrive); if (drive_number == DriveIndex) { r = TRUE; if (drive_letters != NULL) drive_letters[i++] = *drive; // The drive type should be the same for all volumes, so we can overwrite if (drive_type != NULL) *drive_type = _drive_type; } } out: if (drive_letters != NULL) drive_letters[i] = 0; return r; }
/* * Open a drive or volume with optional write and lock access * Returns INVALID_HANDLE_VALUE (/!\ which is DIFFERENT from NULL /!\) on failure. * This call is quite risky (left unchecked, inadvertently passing 0 as index would * return a handle to C:, which we might then proceed to unknowingly repartition!), * so we apply the following mitigation factors: * - Valid indexes must belong to a specific range [DRIVE_INDEX_MIN; DRIVE_INDEX_MAX] * - When opening for write access, we lock the volume. If that fails, which would * typically be the case on C:\ or any other drive in use, we report failure * - We report the full path of any drive that was successfully opened for write acces */ HANDLE GetDriveHandle(DWORD DriveIndex, char* DriveLetter, BOOL bWriteAccess, BOOL bLockDrive) { BOOL r; DWORD size; HANDLE hDrive = INVALID_HANDLE_VALUE; STORAGE_DEVICE_NUMBER_REDEF device_number = {0}; UINT drive_type; char drives[26*4]; /* "D:\", "E:\", etc. */ char *drive = drives; char logical_drive[] = "\\\\.\\#:"; char physical_drive[24]; if ((DriveIndex < DRIVE_INDEX_MIN) || (DriveIndex > DRIVE_INDEX_MAX)) { uprintf("WARNING: Bad index value. Please check the code!\n"); } DriveIndex -= DRIVE_INDEX_MIN; // If no drive letter is requested, open a physical drive if (DriveLetter == NULL) { safe_sprintf(physical_drive, sizeof(physical_drive), "\\\\.\\PHYSICALDRIVE%d", DriveIndex); hDrive = CreateFileA(physical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0), FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (hDrive == INVALID_HANDLE_VALUE) { uprintf("Could not open drive %s: %s\n", physical_drive, WindowsErrorString()); goto out; } if (bWriteAccess) { uprintf("Caution: Opened %s drive for write access\n", physical_drive); } } else { *DriveLetter = ' '; size = GetLogicalDriveStringsA(sizeof(drives), drives); if (size == 0) { uprintf("GetLogicalDriveStrings failed: %s\n", WindowsErrorString()); goto out; } if (size > sizeof(drives)) { uprintf("GetLogicalDriveStrings: buffer too small (required %d vs %d)\n", size, sizeof(drives)); goto out; } hDrive = INVALID_HANDLE_VALUE; for ( ;*drive; drive += safe_strlen(drive)+1) { if (!isalpha(*drive)) continue; *drive = (char)toupper((int)*drive); if (*drive < 'C') { continue; } /* IOCTL_STORAGE_GET_DEVICE_NUMBER's STORAGE_DEVICE_NUMBER.DeviceNumber is not unique! An HDD, a DVD and probably other drives can have the same value there => Use GetDriveType() to filter out unwanted devices. See https://github.com/pbatard/rufus/issues/32 for details. */ drive_type = GetDriveTypeA(drive); // NB: the HP utility allows drive_type == DRIVE_FIXED, which we don't allow by default // Using Alt-F in Rufus does enable listing, but this mode is unsupported. if ((drive_type != DRIVE_REMOVABLE) && ((!enable_fixed_disks) || (drive_type != DRIVE_FIXED))) continue; safe_sprintf(logical_drive, sizeof(logical_drive), "\\\\.\\%c:", drive[0]); hDrive = CreateFileA(logical_drive, GENERIC_READ|(bWriteAccess?GENERIC_WRITE:0), FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); if (hDrive == INVALID_HANDLE_VALUE) { uprintf("Warning: could not open drive %c: %s\n", drive[0], WindowsErrorString()); continue; } r = DeviceIoControl(hDrive, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &device_number, sizeof(device_number), &size, NULL); if ((!r) || (size <= 0)) { uprintf("IOCTL_STORAGE_GET_DEVICE_NUMBER failed for device %s: %s\n", logical_drive, WindowsErrorString()); } else if (device_number.DeviceNumber == DriveIndex) { break; } safe_closehandle(hDrive); } if (hDrive == INVALID_HANDLE_VALUE) { goto out; } if (bWriteAccess) { uprintf("Caution: Opened %s drive for write access\n", logical_drive); } *DriveLetter = *drive?*drive:' '; } if ((bLockDrive) && (!DeviceIoControl(hDrive, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &size, NULL))) { uprintf("Could not get exclusive access to %s %s\n", logical_drive, WindowsErrorString()); safe_closehandle(hDrive); goto out; } out: return hDrive; }
QList<ProcessInfo> runningProcesses() { EnumWindowsProcParam param; HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); if (!snapshot) return param.processes; QStringList deviceList; const DWORD bufferSize = 1024; char buffer[bufferSize + 1] = { 0 }; if (QSysInfo::windowsVersion() <= QSysInfo::WV_5_2) { const DWORD size = GetLogicalDriveStringsA(bufferSize, buffer); deviceList = QString::fromLatin1(buffer, size).split(QLatin1Char(char(0)), QString::SkipEmptyParts); } QLibrary kernel32(QLatin1String("Kernel32.dll")); kernel32.load(); QueryFullProcessImageNamePtr pQueryFullProcessImageNamePtr = (QueryFullProcessImageNamePtr) kernel32 .resolve("QueryFullProcessImageNameA"); QLibrary psapi(QLatin1String("Psapi.dll")); psapi.load(); GetProcessImageFileNamePtr pGetProcessImageFileNamePtr = (GetProcessImageFileNamePtr) psapi .resolve("GetProcessImageFileNameA"); PROCESSENTRY32 processStruct; processStruct.dwSize = sizeof(PROCESSENTRY32); bool foundProcess = Process32First(snapshot, &processStruct); while (foundProcess) { HANDLE procHandle = OpenProcess(QSysInfo::windowsVersion() > QSysInfo::WV_5_2 ? KDSYSINFO_PROCESS_QUERY_LIMITED_INFORMATION : PROCESS_QUERY_INFORMATION, false, processStruct .th32ProcessID); bool succ = false; QString executablePath; DWORD bufferSize = 1024; if (QSysInfo::windowsVersion() > QSysInfo::WV_5_2) { succ = pQueryFullProcessImageNamePtr(procHandle, 0, buffer, &bufferSize); executablePath = QString::fromLatin1(buffer); } else if (pGetProcessImageFileNamePtr) { succ = pGetProcessImageFileNamePtr(procHandle, buffer, bufferSize); executablePath = QString::fromLatin1(buffer); for (int i = 0; i < deviceList.count(); ++i) { executablePath.replace(QString::fromLatin1( "\\Device\\HarddiskVolume%1\\" ).arg(i + 1), deviceList.at(i)); } } if (succ) { const quint32 pid = processStruct.th32ProcessID; param.seenIDs.append(pid); ProcessInfo info; info.id = pid; info.name = executablePath; param.processes.append(info); } CloseHandle(procHandle); foundProcess = Process32Next(snapshot, &processStruct); } if (snapshot) CloseHandle(snapshot); kernel32.unload(); return param.processes; }