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;
        }
    }
Exemple #2
0
/*
 * 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;
}
Exemple #3
0
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;
        }
    }
}
Exemple #4
0
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;
}
Exemple #6
0
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;
}
Exemple #9
0
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;
}
Exemple #11
0
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;
}
Exemple #12
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();
}
Exemple #13
0
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;
}
Exemple #14
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;
}
Exemple #15
0
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;
}
Exemple #16
0
/*
 * 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;
}
Exemple #17
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];	/* "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;
}
Exemple #18
0
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;
}
Exemple #19
0
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;
}
Exemple #20
0
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 = &mp; 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(&not_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(&not_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);
}
Exemple #21
0
/*
 * 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;
}
Exemple #22
0
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
}
Exemple #23
0
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;
}
Exemple #24
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;
}
Exemple #25
0
/*
 * 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;
}