std::string get_root_uuid() {
  using tchar_str = std::basic_string<TCHAR>;
  string uuid;
  TCHAR buf[max_drive_name];      // temporary buffer for volume name
  tchar_str drive = TEXT("c:\\"); // string "template" for drive specifier
  // walk through legal drive letters, skipping floppies
  for (TCHAR i = TEXT('c'); i < TEXT('z'); i++) {
    // Stamp the drive for the appropriate letter.
    drive[0] = i;
    if (GetVolumeNameForVolumeMountPoint(drive.c_str(), buf, max_drive_name)) {
      tchar_str drive_name = buf;
      auto first = drive_name.find(TEXT("Volume{"));
      if (first != std::string::npos) {
        first += 7;
        auto last = drive_name.find(TEXT("}"), first);
        if (last != std::string::npos && last > first) {
          mv(uuid, drive_name.substr(first, last - first));
          // UUIDs are formatted as 8-4-4-4-12 hex digits groups
          auto cpy = uuid;
          replace_if(cpy.begin(), cpy.end(), ::isxdigit, 'F');
          // discard invalid UUID
          if (cpy != uuid_format)
            uuid.clear();
          else
            return uuid; // return first valid UUID we get
        }
      }
    }
  }
  return uuid;
}
QString QStorageInfo_CustomPrivate::uriForDrive(const QString &drive)
{
    WCHAR uri[50];
    if (GetVolumeNameForVolumeMountPoint((WCHAR *)drive.utf16(), uri, 50))
        return QString::fromUtf16(reinterpret_cast<const unsigned short *>(uri));
    return QString();
}
QString getGUID(const QString &mountPoint) {
    const size_t  maxGUIDPath = 50;
    wchar_t buffer[maxGUIDPath + 1];
    qDebug()<<"GetGUIDof: "<<mountPoint;
    GetVolumeNameForVolumeMountPoint(mountPoint.toStdWString().c_str(), buffer, maxGUIDPath);
    qDebug()<<"GetGUIDof: "<<QString("").fromStdWString(buffer).toLatin1()<< "  "<<GetLastError();
    return QString(QString("").fromStdWString(buffer).toLatin1()).remove("\\\\?\\Volume").remove("\\");
}
Exemple #4
0
void GetSystemDriveGUID(Row& r) {
  char buf[51] = {0};
  auto sysRoot = getSystemRoot().root_name().string() + "\\";
  if (GetVolumeNameForVolumeMountPoint(
          sysRoot.c_str(), static_cast<LPSTR>(buf), 50)) {
    r["device"] = SQL_TEXT(buf);
  }
}
Exemple #5
0
static int
sync_win32 (void)
{
  DWORD n1, n2;

  n1 = GetLogicalDriveStrings (0, NULL);
  if (n1 == 0)
    return -1;

  TCHAR buffer[n1+2]; /* sic */
  n2 = GetLogicalDriveStrings (n1, buffer);
  if (n2 == 0)
    return -1;

  TCHAR *p = buffer;

  /* The MSDN example code itself assumes that there is always one
   * drive in the system.  However we will be better than that and not
   * make the assumption ...
   */
  while (*p) {
    HANDLE drive;
    DWORD drive_type;

    /* Ignore removable drives. */
    drive_type = GetDriveType (p);
    if (drive_type == DRIVE_FIXED) {
      /* To open the volume you have to specify the volume name, not
       * the mount point.  MSDN documents use of the constant 50
       * below.
       */
      TCHAR volname[50];
      if (!GetVolumeNameForVolumeMountPoint (p, volname, 50))
        return -1;

      drive = CreateFile (volname, GENERIC_READ|GENERIC_WRITE,
                          FILE_SHARE_READ|FILE_SHARE_WRITE,
                          NULL, OPEN_EXISTING, 0, 0);
      if (drive == INVALID_HANDLE_VALUE)
        return -1;

      BOOL r;
      /* This always fails in Wine:
       * http://bugs.winehq.org/show_bug.cgi?id=14915
       */
      r = FlushFileBuffers (drive);
      CloseHandle (drive);
      if (!r)
        return -1;
    }

    /* Skip to next \0 character. */
    while (*p++);
  }

  return 0;
}
Exemple #6
0
BOOL GetNtfsNumberOfSectors(wchar_t * rootPath, uint64 * pNumberOfSectors, DWORD *pBytesPerSector)
{
    HANDLE hDevice;
    BOOL bResult;
    DWORD nbytes, dwError;
    size_t len;
    NTFS_VOLUME_DATA_BUFFER ntfsvdb;
    wchar_t szVolumeGUID[128];

    // get volume name
    if (!GetVolumeNameForVolumeMountPoint(rootPath,szVolumeGUID,ARRAYSIZE(szVolumeGUID)))
    {
        return FALSE;
    }

    // strip trailing backslash from volume GUID (otherwise it means root dir)
    len = wcslen(szVolumeGUID);
    if (len>0)
        --len;
    if (szVolumeGUID[len]==L'\\')
        szVolumeGUID[len]=0;

    hDevice = CreateFile(szVolumeGUID,
                         GENERIC_READ,
                         FILE_SHARE_READ | FILE_SHARE_WRITE,
                         NULL,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         NULL);

    if (hDevice == INVALID_HANDLE_VALUE)
        return (FALSE);

    bResult = DeviceIoControl(hDevice,
                              FSCTL_GET_NTFS_VOLUME_DATA,
                              NULL, 0,
                              &ntfsvdb, sizeof(ntfsvdb),
                              &nbytes,
                              (LPOVERLAPPED) NULL);

    if (bResult)
    {
        if (pNumberOfSectors)
            *pNumberOfSectors = ntfsvdb.NumberSectors.QuadPart;
        if (pBytesPerSector)
            *pBytesPerSector = ntfsvdb.BytesPerSector;
    }

    dwError = GetLastError ();
    CloseHandle(hDevice);
    SetLastError (dwError);

    return (bResult);
}
Exemple #7
0
BOOL _GetDiskFreeSpaceEx(
  LPCTSTR lpDirectoryName,                 // ディレクトリ名
  PULARGE_INTEGER lpFreeBytesAvailable,    // 呼び出し側が利用できるバイト数
  PULARGE_INTEGER lpTotalNumberOfBytes,    // ディスク全体のバイト数
  PULARGE_INTEGER lpTotalNumberOfFreeBytes // ディスク全体の空きバイト数
)
{
	TCHAR szVolumePathName[MAX_PATH] = _T("");
	if( GetVolumePathName( lpDirectoryName, szVolumePathName, MAX_PATH) == FALSE ){
		return GetDiskFreeSpaceEx( lpDirectoryName, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes );
	}
	TCHAR szMount[MAX_PATH] = _T("");
	if( GetVolumeNameForVolumeMountPoint(szVolumePathName, szMount, MAX_PATH) == FALSE ){
		return GetDiskFreeSpaceEx( szVolumePathName, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes );
	}
	return GetDiskFreeSpaceEx( szMount, lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes );
}
Exemple #8
0
bool mountFolder(const QString &srcDrive, const QString &tgtPath, QString &error)
{
	QString drv = QDir::cleanPath(srcDrive)+"\\";
	QString nat = QDir::toNativeSeparators(tgtPath);
#ifdef _WIN32
	LPCWSTR lpszVolumeMountPoint = (LPCWSTR)drv.utf16();
	LPWSTR  lpszVolumeName = '\0';

	if (GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint, lpszVolumeName, 100) == NO_ERROR)
	{
		lpszVolumeMountPoint = (LPCWSTR)nat.utf16();
		if (SetVolumeMountPoint(lpszVolumeMountPoint, lpszVolumeName) == NO_ERROR)
			return true;
	}
#endif
	error = getLastWinError();
	return false;
}
Exemple #9
0
int ExtendFileSystem (HWND hwndDlg , wchar_t *lpszVolume, Password *pVolumePassword, int VolumePkcs5, int VolumePim, uint64 newDataAreaSize)
{
    wchar_t szVolumeGUID[128];
    int driveNo = -1;
    wchar_t rootPath[] = L"A:\\";
    enum EV_FileSystem fs;
    DWORD dwError;
    int nStatus = ERR_SUCCESS;
    DWORD BytesPerSector;

    // mount and resize file system

    DebugAddProgressDlgStatus (hwndDlg, L"Mounting volume ...\r\n");

    nStatus=MountVolTemp(hwndDlg, lpszVolume, &driveNo, pVolumePassword, VolumePkcs5, VolumePim);
    if (nStatus!=ERR_SUCCESS)
    {
        driveNo = -1;
        goto error;
    }

    rootPath[0] += driveNo;

    if ( !GetFileSystemType(rootPath,&fs) )
    {
        dwError = GetLastError();
        if (dwError == ERROR_UNRECOGNIZED_VOLUME)
        {
            // raw volume with unrecognized file system -> return with no error
            nStatus = ERR_SUCCESS;
            goto error;
        }
        nStatus = ERR_OS_ERROR;
        goto error;
    }

    if (fs != EV_FS_TYPE_RAW && fs != EV_FS_TYPE_NTFS )
    {
        // FsctlExtendVolume only supports NTFS and RAW -> return with no error
        nStatus = ERR_SUCCESS;
        goto error;
    }

    // Get volume GUID
    if (!GetVolumeNameForVolumeMountPoint(rootPath,szVolumeGUID,ARRAYSIZE(szVolumeGUID)))
    {
        nStatus = ERR_OS_ERROR;
        goto error;
    }
    else
    {
        // strip trailing backslash from volume GUID (otherwise it means root dir)
        size_t len = wcslen(szVolumeGUID);
        if (len>0) --len;
        if (szVolumeGUID[len]==L'\\') szVolumeGUID[len]=0;
    }

    // Get Sector Size
    if ( !GetNtfsNumberOfSectors(rootPath, NULL, &BytesPerSector) )
    {
        nStatus = ERR_OS_ERROR;
        goto error;
    }

    DebugAddProgressDlgStatus (hwndDlg, L"Extending file system ...\r\n");

    // extend volume
    nStatus = FsctlExtendVolume(szVolumeGUID, newDataAreaSize/BytesPerSector );

error:

    dwError = GetLastError();

    if (driveNo>=0)
    {
        DebugAddProgressDlgStatus (hwndDlg, L"Unmounting volume ...\r\n");
        UnmountVolume (hwndDlg, driveNo, TRUE);
    }

    SetLastError (dwError);

    return nStatus;
}
Exemple #10
0
HRESULT
pGetVolumeDeviceNameForMountPointW(
	__in LPCWSTR VolumeMountPoint,
	__out LPWSTR* VolumeDeviceName)
{
	// The lpszVolumeMountPoint parameter may be a drive letter with 
	// appended backslash (\), such as "D:\". Alternatively, it may be 
	// a path to a volume mount point, again with appended backslash (\), 
	// such as "c:\mnt\edrive\".

	// A reasonable size for the buffer to accommodate the largest possible 
	// volume name is 50 characters --> wrong 100

	HRESULT hr;

	XTLASSERT(NULL != VolumeDeviceName);
	if (NULL == VolumeDeviceName)
	{
		return E_POINTER;
	}

	*VolumeDeviceName = NULL;

	const DWORD MAX_VOLUMENAME_LEN = 50;
	DWORD volumeDeviceNameLength = MAX_VOLUMENAME_LEN;
	
	XTL::AutoProcessHeapPtr<TCHAR> volumeDeviceName = 
		static_cast<TCHAR*>(
			HeapAlloc(
				GetProcessHeap(), 
				HEAP_ZERO_MEMORY, 
				volumeDeviceNameLength * sizeof(TCHAR)));

	if (volumeDeviceName.IsInvalid())
	{
		XTLTRACE2(NdasVolTrace, 0,
			"HeapAlloc for %d bytes failed.\n", volumeDeviceNameLength);
		return E_OUTOFMEMORY;
	}

	BOOL success = GetVolumeNameForVolumeMountPoint(
		VolumeMountPoint, 
		volumeDeviceName, 
		volumeDeviceNameLength);

	if (!success)
	{
		hr = HRESULT_FROM_WIN32(GetLastError());
		XTLTRACE2(NdasVolTrace, 0,
			"GetVolumeNameForVolumeMountPoint(%ls) failed, hr=0x%X\n", 
			VolumeMountPoint, hr);
		return hr;
	}

	// Volume Name is a format of \\?\Volume{XXXX}\ with trailing backslash
	// Volume device name is that of \\.\Volume{XXXX} without trailing backslash

	_ASSERTE(_T('\\') == volumeDeviceName[0]);
	_ASSERTE(_T('\\') == volumeDeviceName[1]);
	_ASSERTE(_T('?')  == volumeDeviceName[2]);
	_ASSERTE(_T('\\') == volumeDeviceName[3]);

	if (_T('\\') == volumeDeviceName[0] &&
		_T('\\') == volumeDeviceName[1] &&
		_T('?') == volumeDeviceName[2] &&
		_T('\\') == volumeDeviceName[3])
	{
		// replace ? to .
		volumeDeviceName[2] = _T('.');
	}

	// remove trailing backslash
	pRemoveTrailingBackslash(volumeDeviceName);

	XTLTRACE2(NdasVolTrace, 2, 
		"VolumeMountPoint(%ls)=>Volume(%ls)\n", 
		VolumeMountPoint, volumeDeviceName);

	*VolumeDeviceName = volumeDeviceName.Detach();

	return S_OK;
}
// This does the same as GetVolumePathNamesForVolumeNameW() on Windows XP and
// later. It is built into 32 bit versions of this library to make sure that
// the DLL can load correctly on Windows 2000 as well.
BOOL
WINAPI
ImScsiLegacyGetVolumePathNamesForVolumeName(
__in   LPCWSTR lpszVolumeName,
__out  LPWSTR  lpszVolumePathNames,
__in   DWORD   cchBufferLength,
__out  PDWORD  lpcchReturnLength)
{
    *lpcchReturnLength = 0;

    DWORD dw;
    dw;

    LPWSTR cur_ptr = lpszVolumePathNames;
    LPWSTR end_ptr = lpszVolumePathNames + cchBufferLength;

    WCHAR vol_target[MAX_PATH];

    wcsncpy(vol_target, lpszVolumeName + 4, 44);
    vol_target[44] = 0;

    if (!QueryDosDevice(vol_target, vol_target, _countof(vol_target)))
    {
        return FALSE;
    }

    WHeapMem<WCHAR> dosdevs(UNICODE_STRING_MAX_BYTES,
        HEAP_GENERATE_EXCEPTIONS);

    if (!QueryDosDevice(NULL, dosdevs, (DWORD)dosdevs.Count()))
    {
        return FALSE;
    }

    DWORD good = cchBufferLength >= 2;
    
    *lpcchReturnLength = 2;

    WCHAR dev_target[MAX_PATH];

    SIZE_T length;
    for (LPCWSTR ptr = dosdevs;
        (length = wcslen(ptr)) != 0;
        ptr += length + 1)
    {
        if (good)
        {
            *cur_ptr = 0;
        }

        if ((length != 2) ||
            (ptr[1] != L':') ||
            (!QueryDosDevice(ptr, dev_target, _countof(dev_target))) ||
            (_wcsicmp(dev_target, vol_target) != 0))
        {
            continue;
        }

        *lpcchReturnLength += 4;

        if ((cur_ptr + 4) >= end_ptr)
        {
            good = FALSE;
        }

        if (good)
        {
            swprintf(cur_ptr, L"%ws\\", ptr);
            cur_ptr += 4;
        }
    }

    WCHAR vol_name[50];

    HANDLE volume = FindFirstVolume(vol_name, _countof(vol_name));

    if (volume == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    DWORD error_mode = SetErrorMode(SEM_FAILCRITICALERRORS |
        SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);

    do
    {
        HANDLE vol_mnt = FindFirstVolumeMountPoint(vol_name, dosdevs,
            (DWORD)dosdevs.Count());

        if (vol_mnt == INVALID_HANDLE_VALUE)
        {
            continue;
        }

        do
        {
            WMem<WCHAR> mnt_path;
            
            mnt_path = ImDiskAllocPrintF(L"%1!ws!%2!ws!", vol_name, dosdevs);

            if (!mnt_path)
            {
                continue;
            }

            WCHAR mnt_vol_name[50];
            if (!GetVolumeNameForVolumeMountPoint(mnt_path, mnt_vol_name,
                _countof(mnt_vol_name)))
            {
                continue;
            }

            if (_wcsicmp(mnt_vol_name, lpszVolumeName) == 0)
            {
                if (ImScsiLegacyGetVolumePathNamesForVolumeName(vol_name,
                    vol_target, _countof(vol_target), &dw))
                {
                    mnt_path = ImDiskAllocPrintF(L"%1!ws!%2!ws!", vol_target,
                        dosdevs);

                }

                size_t len = wcslen(mnt_path) + 1;

                *lpcchReturnLength += (DWORD)len;

                if ((cur_ptr + len) >= end_ptr)
                {
                    good = FALSE;
                }

                if (good)
                {
                    wcscpy(cur_ptr, mnt_path);
                    cur_ptr += len;
                }
            }

        } while (FindNextVolumeMountPoint(vol_mnt, dosdevs,
            (DWORD)dosdevs.Count()));
        
        FindVolumeMountPointClose(vol_mnt);

    } while (FindNextVolume(volume, vol_name, _countof(vol_name)));

    FindVolumeClose(volume);

    SetErrorMode(error_mode);

    if (cur_ptr >= end_ptr)
    {
        good = FALSE;
    }

    if (good)
    {
        *cur_ptr = 0;
        ++*lpcchReturnLength;
    }
    else
    {
        SetLastError(ERROR_MORE_DATA);
    }

    return good;
}
Exemple #12
0
	void g_scan_drives (DWORD mask)
	{
	//pfc::hires_timer timer;
	//timer.start();
	//profiler(scandrives);
#if 0
		{
			TCHAR volume[128], mount[512];
			memset(volume, 0, sizeof(volume));
			HANDLE vol = FindFirstVolume(volume, tabsize(volume)-1);
			if (vol != INVALID_HANDLE_VALUE)
			{
				do
				{
					console::formatter() << "Volume: " << pfc::stringcvt::string_utf8_from_wide(volume, 128);
					memset(mount, 0, sizeof(mount));
					HANDLE hmount = FindFirstVolumeMountPoint(volume, mount, tabsize(mount)-1);
					if (hmount != INVALID_HANDLE_VALUE)
					{
						do
						{
							console::formatter() << "mountpoint: " << pfc::stringcvt::string_utf8_from_wide(mount, tabsize(mount));
							memset(mount, 0, sizeof(mount));
						}
						while (FindNextVolumeMountPoint(hmount, mount, tabsize(mount)-1) || GetLastError() != ERROR_NO_MORE_FILES);
						FindVolumeMountPointClose(hmount);

					}
					memset(volume, 0, sizeof(volume));
				}
				while (FindNextVolume(vol, volume, tabsize(volume)-1) || GetLastError() != ERROR_NO_MORE_FILES);
				FindVolumeClose(vol);
			}
		}
#endif
		if (mask)
		{
			t_volumes volumes;
			build_volumes_v2(volumes);

			t_size i =0;
			for (i=0; i<32; i++)
			{
				if (mask & 1<<i) 
				{
					pfc::string8 drive; drive.add_byte('A'+i);
					pfc::array_t<WCHAR> path, itunesdb_path;
					path.append_single('A'+i);
					path.append_fromptr(L":\\", 3);
					{
						WCHAR volumename[129];
						memset(volumename, 0, sizeof(volumename));
						if (GetDriveType(path.get_ptr()) == DRIVE_REMOVABLE && GetVolumeNameForVolumeMountPoint(path.get_ptr(), volumename, 128))
						{
							t_size indexvol;
							//if (volumes.find(volumename, 128, indexvol))
							{
								//FIXME WTF
								if (volumes.find(volumename, 128, indexvol) /*&& g_check_devid_is_ipod(volumes[indexvol].disk_device_id)*/)
								{
									ipod_device_ptr_t temp = new ipod_device_t('A' + i, volumes[indexvol].model, volumes[indexvol].shuffle, volumes[indexvol].disk_device_id.get_ptr(), volumes[indexvol].volume_name.get_ptr(), volumes[indexvol].driver_symbolic_path.get_ptr(), volumes[indexvol].instance, device_properties_t());

									pfc::string8 pl;
									try {
										g_get_device_xml(temp, pl);
#if 0//_DEBUG
										{
											file::ptr f;
											abort_callback_dummy noabort;
											filesystem::g_open_read(f, "i:\\nano6g.plist", noabort);
											pfc::array_staticsize_t<char> d(pfc::downcast_guarded<t_uint32>(f->get_size_ex(noabort)));
											f->read(d.get_ptr(), d.get_size(), noabort);
											pl.set_string(d.get_ptr(), d.get_size());
										}
#endif
										g_get_artwork_info(pl, temp->m_device_properties);
									} 
									catch (const pfc::exception & ex) 
									{
										console::formatter() << "iPod manager: Failed to get iPod checkpoint data - " << ex.what() << ". Artwork functionality will be unavailable.";
										temp->m_device_properties.m_artwork_formats.remove_all();
									};
									//console::formatter() << "New iPod detected. Drive: " << drive << " Device Instance ID: " << pfc::stringcvt::string_utf8_from_wide(volumes[indexvol].disk_device_id);
									if (m_abort)
										g_drive_manager.add_drive(temp, *m_abort);
									else
										g_drive_manager.add_drive(temp, abort_callback_dummy());
								}
								//else
								//	console::formatter() << "New drive detected. Drive: " << drive << " Device Instance ID: " << pfc::stringcvt::string_utf8_from_wide(volumes[indexvol].disk_device_id);// << " Volume ID: " << pfc::stringcvt::string_utf8_from_wide(volumes[indexvol].volume_name);
							}
						}
						//else
						//	console::formatter() << "Drive is not expected type or GetVolumeNameForVolumeMountPoint failed. Drive: " << drive;
					}
				}

			}
		}
		//console::formatter() << "old:" << timer.query();
	}
Exemple #13
0
BOOL
get_all_removable_disks(struct tagDrives *g_drives)
{
    WCHAR	caDrive[4];
	WCHAR	volume[BUFSIZE];
	int		nLoopIndex;
	DWORD	dwDriveMask;
	unsigned int g_count=0;


	caDrive[0]	= 'A';
    caDrive[1]	= ':';
    caDrive[2]	= '\\';
    caDrive[3]	= 0;





	// Get all drives in the system.
    dwDriveMask = GetLogicalDrives();


	if(dwDriveMask == 0)
	{
		PyErr_SetString(DriveError, "GetLogicalDrives failed");
		return FALSE;
	}


	// Loop for all drives (MAX_DRIVES = 26)


    for(nLoopIndex = 0; nLoopIndex < MAX_DRIVES; nLoopIndex++)
    {
        // if a drive is present (we cannot ignore the A and B drives as there
        // are people out there that think mapping devices to use those letters
        // is a good idea, sigh)
		if(dwDriveMask & 1)
        {
            caDrive[0] = 'A' + nLoopIndex;


			// If a drive is removable
			if(GetDriveType(caDrive) == DRIVE_REMOVABLE)
			{
				//Get its volume info and store it in the global variable.
				if(GetVolumeNameForVolumeMountPoint(caDrive, volume, BUFSIZE))
	            {
		            g_drives[g_count].letter = caDrive[0];
					wcscpy_s(g_drives[g_count].volume, BUFSIZE, volume);
					g_count ++;
				}

			}
		}
		dwDriveMask >>= 1;
	}


	// success if atleast one removable drive is found.
	if(g_count == 0)
	{
	    PyErr_SetString(DriveError, "No removable drives found");
		return FALSE;
	}
	return TRUE;

}
Exemple #14
0
int __cdecl _tmain(int argc, TCHAR** argv)
{
	TCHAR* lpPath;
	TCHAR mountPoint[MAX_PATH];
	TCHAR volumeName[100];
	LPTSTR lpVolumeDevicePath;
	HANDLE hVolume;

	if (argc > 1)
	{
		if (0 == lstrcmpi(_T("/trace"), argv[1]) ||
			0 == lstrcmpi(_T("-trace"), argv[1]))
		{
			NdasVolSetTrace(0x0000ffff, 0xffffffff, 5);
			--argc;
			++argv;
		}
	}

	lpPath = (argc < 2) ? _T("C:") : argv[1]; 
	lpVolumeDevicePath = lpPath;

	_tprintf(_T("Device Name: %s\n"), lpVolumeDevicePath);

	if (NdasIsNdasPath(lpVolumeDevicePath))
	{
		_tprintf(_T("%s is on the NDAS device.\n"), lpVolumeDevicePath );
		if (GetVolumePathName(lpVolumeDevicePath, mountPoint, RTL_NUMBER_OF(mountPoint)))
		{
			if (GetVolumeNameForVolumeMountPoint(
				mountPoint, 
				volumeName, RTL_NUMBER_OF(volumeName)))
			{
				int len = lstrlen(volumeName);
				// _tprintf(_T("VolumeName=%s\n"), volumeName);
				// remove trailing backslash
				if (len > 0 && _T('\\') == volumeName[len-1])
				{
					volumeName[len-1] = _T('\0');
				}
				// replace \\?\Volume... to \\.\Volume...
				if (_T('\\') == volumeName[0] && _T('\\') == volumeName[1] &&
					_T('?') == volumeName[2] && _T('\\') == volumeName[3])
				{
					volumeName[2] = _T('.');
				}
				// _tprintf(_T("VolumeName=%s\n"), volumeName);
				hVolume = CreateFile(volumeName, GENERIC_READ, 
					FILE_SHARE_READ | FILE_SHARE_WRITE,
					NULL, OPEN_EXISTING, 0, NULL);
				if (INVALID_HANDLE_VALUE != hVolume)
				{
					NDAS_SCSI_LOCATION loc;
					if (NdasGetNdasScsiLocationForVolume(hVolume,&loc))
					{
						_tprintf(_T("NDAS_SCSI_LOCATION=(%d,%d,%d)"), 
							loc.SlotNo, loc.TargetID, loc.LUN);
					}
					else
					{
						_tprintf(_T("NdasGetNdasScsiLocationForVolume failed.\n"));
						_tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError());
					}
					CloseHandle(hVolume);
				}
				else
				{
					_tprintf(_T("Opening the volume %s failed.\n"), volumeName);
					_tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError());
				}
			}
			else
			{
				_tprintf(_T("GetVolumeNameForVolumeMountPoint %s failed.\n"), mountPoint);
				_tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError());
			}
		}
		else
		{
			_tprintf(_T("GetVolumePathName %s failed.\n"), lpVolumeDevicePath);
			_tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError());
		}
	}
	else
	{
		_tprintf(_T("Error %u(%X)\n"), GetLastError(), GetLastError());
	}
	return 0;
}
static int adddrive (const TCHAR *drvpath, int bus, int pathid, int targetid, int lunid, int scanmode)
{
	struct dev_info_spti *di;
	int cnt = total_devices, i;
	int freeit = 1;

	if (cnt >= MAX_TOTAL_SCSI_DEVICES)
		return 0;
	for (i = 0; i < total_devices; i++) {
		di = &dev_info[i];
		if (!_tcscmp (drvpath, di->drvpath))
			return 0;
	}
	write_log (L"SPTI: unit %d '%s' added\n", total_devices, drvpath);
	di = &dev_info[total_devices];
	di->drvpath = my_strdup (drvpath);
	di->type = 0;
	di->bus = bus;
	di->path = pathid;
	di->target = targetid;
	di->lun = lunid;
	di->scanmode = scanmode;
	di->drvletter = 0;
	di->enabled = true;

	for (TCHAR drvletter = 'C'; drvletter <= 'Z'; drvletter++) {
		TCHAR drvname[10];
		TCHAR volname[MAX_DPATH], volname2[MAX_DPATH];
		_stprintf (drvname, L"%c:\\", drvletter);
		if (GetVolumeNameForVolumeMountPoint (drvname, volname, sizeof volname / sizeof (TCHAR))) {
			TCHAR drvpath2[MAX_DPATH];
			_stprintf (drvpath2, L"%s\\", di->drvpath);
			if (GetVolumeNameForVolumeMountPoint (drvpath2, volname2, sizeof volname2 / sizeof (TCHAR))) {
				if (!_tcscmp (volname, volname2)) {
					di->drvletter = drvletter;
					_tcscpy (di->drvlettername, drvname);
					break;
				}
			}
		}
	}


	total_devices++;
	unittable[cnt] = cnt + 1;
	if (open_scsi_device2 (&dev_info[cnt], cnt)) {
		for (i = 0; i < cnt; i++) {
			if (!memcmp (di->inquirydata, dev_info[i].inquirydata, INQUIRY_SIZE) && di->scanmode != dev_info[i].scanmode) {
				write_log (L"duplicate device, skipped..\n");
				break;
			}
		}
		if (i == cnt) {
			freeit = 0;
			close_scsi_device2 (&dev_info[cnt]);
		}
	}
	if (freeit) {
		free_scsi_device (&dev_info[cnt]);
		total_devices--;
	}
	unittable[cnt] = 0;
	return 1;
}
Exemple #16
0
int TCFormatVolume (volatile FORMAT_VOL_PARAMETERS *volParams)
{
	int nStatus;
	PCRYPTO_INFO cryptoInfo = NULL;
	HANDLE dev = INVALID_HANDLE_VALUE;
	DWORD dwError;
	char header[TC_VOLUME_HEADER_EFFECTIVE_SIZE];
	unsigned __int64 num_sectors, startSector;
	fatparams ft;
	FILETIME ftCreationTime;
	FILETIME ftLastWriteTime;
	FILETIME ftLastAccessTime;
	BOOL bTimeStampValid = FALSE;
	BOOL bInstantRetryOtherFilesys = FALSE;
	char dosDev[TC_MAX_PATH] = { 0 };
	char devName[MAX_PATH] = { 0 };
	int driveLetter = -1;
	WCHAR deviceName[MAX_PATH];
	uint64 dataOffset, dataAreaSize;
	LARGE_INTEGER offset;
	BOOL bFailedRequiredDASD = FALSE;
	HWND hwndDlg = volParams->hwndDlg;

	FormatSectorSize = volParams->sectorSize;

	if (FormatSectorSize < TC_MIN_VOLUME_SECTOR_SIZE
		|| FormatSectorSize > TC_MAX_VOLUME_SECTOR_SIZE
		|| FormatSectorSize % ENCRYPTION_DATA_UNIT_SIZE != 0)
	{
		Error ("SECTOR_SIZE_UNSUPPORTED", hwndDlg);
		return ERR_DONT_REPORT; 
	}

	/* WARNING: Note that if Windows fails to format the volume as NTFS and the volume size is
	less than the maximum FAT size, the user is asked within this function whether he wants to instantly
	retry FAT format instead (to avoid having to re-create the whole container again). If the user
	answers yes, some of the input parameters are modified, the code below 'begin_format' is re-executed 
	and some destructive operations that were performed during the first attempt must be (and are) skipped. 
	Therefore, whenever adding or modifying any potentially destructive operations below 'begin_format',
	determine whether they (or their portions) need to be skipped during such a second attempt; if so, 
	use the 'bInstantRetryOtherFilesys' flag to skip them. */

	if (volParams->hiddenVol)
	{
		dataOffset = volParams->hiddenVolHostSize - TC_VOLUME_HEADER_GROUP_SIZE - volParams->size;
	}
	else
	{
		if (volParams->size <= TC_TOTAL_VOLUME_HEADERS_SIZE)
			return ERR_VOL_SIZE_WRONG;

		dataOffset = TC_VOLUME_DATA_OFFSET;
	}

	dataAreaSize = GetVolumeDataAreaSize (volParams->hiddenVol, volParams->size);

	num_sectors = dataAreaSize / FormatSectorSize;

	if (volParams->bDevice)
	{
		StringCbCopyA ((char *)deviceName, sizeof(deviceName), volParams->volumePath);
		ToUNICODE ((char *)deviceName, sizeof(deviceName));

		driveLetter = GetDiskDeviceDriveLetter (deviceName);
	}

	VirtualLock (header, sizeof (header));

	nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
				     header,
				     volParams->ea,
					 FIRST_MODE_OF_OPERATION_ID,
				     volParams->password,
				     volParams->pkcs5,
					  volParams->pim,
					 NULL,
				     &cryptoInfo,
					 dataAreaSize,
					 volParams->hiddenVol ? dataAreaSize : 0,
					 dataOffset,
					 dataAreaSize,
					 0,
					 volParams->headerFlags,
					 FormatSectorSize,
					 FALSE);

	if (nStatus != 0)
	{
		burn (header, sizeof (header));
		VirtualUnlock (header, sizeof (header));
		return nStatus;
	}

begin_format:

	if (volParams->bDevice)
	{
		/* Device-hosted volume */

		DWORD dwResult;
		int nPass;

		if (FakeDosNameForDevice (volParams->volumePath, dosDev, sizeof(dosDev), devName, sizeof(devName), FALSE) != 0)
			return ERR_OS_ERROR;

		if (IsDeviceMounted (devName))
		{
			if ((dev = DismountDrive (devName, volParams->volumePath)) == INVALID_HANDLE_VALUE)
			{
				Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg);
				nStatus = ERR_DONT_REPORT; 
				goto error;
			}

			/* Gain "raw" access to the partition (it contains a live filesystem and the filesystem driver 
			would otherwise prevent us from writing to hidden sectors). */

			if (!DeviceIoControl (dev,
				FSCTL_ALLOW_EXTENDED_DASD_IO,
				NULL,
				0,   
				NULL,
				0,
				&dwResult,
				NULL))
			{
				bFailedRequiredDASD = TRUE;
			}
		}
		else if (IsOSAtLeast (WIN_VISTA) && driveLetter == -1)
		{
			// Windows Vista doesn't allow overwriting sectors belonging to an unformatted partition 
			// to which no drive letter has been assigned under the system. This problem can be worked
			// around by assigning a drive letter to the partition temporarily.

			char szDriveLetter[] = { 'A', ':', 0 };
			char rootPath[] = { 'A', ':', '\\', 0 };
			char uniqVolName[MAX_PATH+1] = { 0 };
			int tmpDriveLetter = -1;
			BOOL bResult = FALSE;

			tmpDriveLetter = GetFirstAvailableDrive ();
 
			if (tmpDriveLetter != -1)
			{
				rootPath[0] += (char) tmpDriveLetter;
				szDriveLetter[0] += (char) tmpDriveLetter;

				if (DefineDosDevice (DDD_RAW_TARGET_PATH, szDriveLetter, volParams->volumePath))
				{
					bResult = GetVolumeNameForVolumeMountPoint (rootPath, uniqVolName, MAX_PATH);

					DefineDosDevice (DDD_RAW_TARGET_PATH|DDD_REMOVE_DEFINITION|DDD_EXACT_MATCH_ON_REMOVE,
						szDriveLetter,
						volParams->volumePath);

					if (bResult 
						&& SetVolumeMountPoint (rootPath, uniqVolName))
					{
						// The drive letter can be removed now
						DeleteVolumeMountPoint (rootPath);
					}
				}
			}
		}

		// For extra safety, we will try to gain "raw" access to the partition. Note that this should actually be
		// redundant because if the filesystem was mounted, we already tried to obtain DASD above. If we failed,
		// bFailedRequiredDASD was set to TRUE and therefore we will perform pseudo "quick format" below. However, 
		// for extra safety, in case IsDeviceMounted() failed to detect a live filesystem, we will blindly
		// send FSCTL_ALLOW_EXTENDED_DASD_IO (possibly for a second time) without checking the result.

		DeviceIoControl (dev,
			FSCTL_ALLOW_EXTENDED_DASD_IO,
			NULL,
			0,   
			NULL,
			0,
			&dwResult,
			NULL);


		// If DASD is needed but we failed to obtain it, perform open - 'quick format' - close - open 
		// so that the filesystem driver does not prevent us from formatting hidden sectors.
		for (nPass = (bFailedRequiredDASD ? 0 : 1); nPass < 2; nPass++)
		{
			int retryCount;

			retryCount = 0;

			// Try exclusive access mode first
			// Note that when exclusive access is denied, it is worth retrying (usually succeeds after a few tries).
			while (dev == INVALID_HANDLE_VALUE && retryCount++ < EXCL_ACCESS_MAX_AUTO_RETRIES)
			{
				dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

				if (retryCount > 1)
					Sleep (EXCL_ACCESS_AUTO_RETRY_DELAY);
			}

			if (dev == INVALID_HANDLE_VALUE)
			{
				// Exclusive access denied -- retry in shared mode
				dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
				if (dev != INVALID_HANDLE_VALUE)
				{
					if (!volParams->bForceOperation && (Silent || (IDNO == MessageBoxW (volParams->hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2))))
					{
						nStatus = ERR_DONT_REPORT; 
						goto error;
					}
				}
				else
				{
					handleWin32Error (volParams->hwndDlg, SRC_POS);
					Error ("CANT_ACCESS_VOL", hwndDlg);
					nStatus = ERR_DONT_REPORT; 
					goto error;
				}
			}

			if (volParams->hiddenVol || bInstantRetryOtherFilesys)
				break;	// The following "quick format" operation would damage the outer volume

			if (nPass == 0)
			{
				char buf [2 * TC_MAX_VOLUME_SECTOR_SIZE];
				DWORD bw;

				// Perform pseudo "quick format" so that the filesystem driver does not prevent us from 
				// formatting hidden sectors
				memset (buf, 0, sizeof (buf));

				if (!WriteFile (dev, buf, sizeof (buf), &bw, NULL))
				{
					nStatus = ERR_OS_ERROR; 
					goto error;
				}

				FlushFileBuffers (dev);
				CloseHandle (dev);
				dev = INVALID_HANDLE_VALUE;
			}
		}

		if (DeviceIoControl (dev, FSCTL_IS_VOLUME_MOUNTED, NULL, 0, NULL, 0, &dwResult, NULL))
		{
			Error ("FORMAT_CANT_DISMOUNT_FILESYS", hwndDlg);
			nStatus = ERR_DONT_REPORT; 
			goto error;
		}
	}
	else
	{
		/* File-hosted volume */

		dev = CreateFile (volParams->volumePath, GENERIC_READ | GENERIC_WRITE,
			(volParams->hiddenVol || bInstantRetryOtherFilesys) ? (FILE_SHARE_READ | FILE_SHARE_WRITE) : 0,
			NULL, (volParams->hiddenVol || bInstantRetryOtherFilesys) ? OPEN_EXISTING : CREATE_ALWAYS, 0, NULL);

		if (dev == INVALID_HANDLE_VALUE)
		{
			nStatus = ERR_OS_ERROR; 
			goto error;
		}

		DisableFileCompression (dev);

		if (!volParams->hiddenVol && !bInstantRetryOtherFilesys)
		{
			LARGE_INTEGER volumeSize;
			volumeSize.QuadPart = dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE;

			if (volParams->sparseFileSwitch && volParams->quickFormat)
			{
				// Create as sparse file container
				DWORD tmp;
				if (!DeviceIoControl (dev, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &tmp, NULL))
				{
					nStatus = ERR_OS_ERROR; 
					goto error;
				}
			}

			// Preallocate the file
			if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
				|| !SetEndOfFile (dev)
				|| SetFilePointer (dev, 0, NULL, FILE_BEGIN) != 0)
			{
				nStatus = ERR_OS_ERROR;
				goto error;
			}
		}
	}

	if (volParams->hiddenVol && !volParams->bDevice && bPreserveTimestamp)
	{
		if (GetFileTime ((HANDLE) dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime) == 0)
			bTimeStampValid = FALSE;
		else
			bTimeStampValid = TRUE;
	}

	if (volParams->hwndDlg && volParams->bGuiMode) KillTimer (volParams->hwndDlg, TIMER_ID_RANDVIEW);

	/* Volume header */

	// Hidden volume setup
	if (volParams->hiddenVol)
	{
		LARGE_INTEGER headerOffset;

		// Check hidden volume size
		if (volParams->hiddenVolHostSize < TC_MIN_HIDDEN_VOLUME_HOST_SIZE || volParams->hiddenVolHostSize > TC_MAX_HIDDEN_VOLUME_HOST_SIZE)
		{		
			nStatus = ERR_VOL_SIZE_WRONG;
			goto error;
		}

		// Seek to hidden volume header location
		
		headerOffset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET;

		if (!SetFilePointerEx ((HANDLE) dev, headerOffset, NULL, FILE_BEGIN))
		{
			nStatus = ERR_OS_ERROR;
			goto error;
		}
	}
	else if (bInstantRetryOtherFilesys)
	{
		// The previous file system format failed and the user wants to try again with a different file system.
		// The volume header had been written successfully so we need to seek to the byte after the header.

		LARGE_INTEGER offset;
		offset.QuadPart = TC_VOLUME_DATA_OFFSET;
		if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN))
		{
			nStatus = ERR_OS_ERROR;
			goto error;
		}
	}

	if (!bInstantRetryOtherFilesys)
	{
		// Write the volume header
		if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header))
		{
			nStatus = ERR_OS_ERROR;
			goto error;
		}

		// To prevent fragmentation, write zeroes to reserved header sectors which are going to be filled with random data
		if (!volParams->bDevice && !volParams->hiddenVol)
		{
			byte buf[TC_VOLUME_HEADER_GROUP_SIZE - TC_VOLUME_HEADER_EFFECTIVE_SIZE];
			DWORD bytesWritten;
			ZeroMemory (buf, sizeof (buf));

			if (!WriteFile (dev, buf, sizeof (buf), &bytesWritten, NULL))
			{
				nStatus = ERR_OS_ERROR;
				goto error;
			}

			if (bytesWritten != sizeof (buf))
			{
				nStatus = ERR_PARAMETER_INCORRECT;
				goto error;
			}
		}
	}

	if (volParams->hiddenVol)
	{
		// Calculate data area position of hidden volume
		cryptoInfo->hiddenVolumeOffset = dataOffset;

		// Validate the offset
		if (dataOffset % FormatSectorSize != 0)
		{
			nStatus = ERR_VOL_SIZE_WRONG; 
			goto error;
		}

		volParams->quickFormat = TRUE;		// To entirely format a hidden volume would be redundant
	}

	/* Data area */
	startSector = dataOffset / FormatSectorSize;

	// Format filesystem

	switch (volParams->fileSystem)
	{
	case FILESYS_NONE:
	case FILESYS_NTFS:

		if (volParams->bDevice && !StartFormatWriteThread())
		{
			nStatus = ERR_OS_ERROR; 
			goto error;
		}

		nStatus = FormatNoFs (hwndDlg, startSector, num_sectors, dev, cryptoInfo, volParams->quickFormat);

		if (volParams->bDevice)
			StopFormatWriteThread();

		break;
		
	case FILESYS_FAT:
		if (num_sectors > 0xFFFFffff)
		{
			nStatus = ERR_VOL_SIZE_WRONG; 
			goto error;
		}

		// Calculate the fats, root dir etc
		ft.num_sectors = (unsigned int) (num_sectors);

#if TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF
#error TC_MAX_VOLUME_SECTOR_SIZE > 0xFFFF
#endif

		ft.sector_size = (uint16) FormatSectorSize;
		ft.cluster_size = volParams->clusterSize;
		memcpy (ft.volume_name, "NO NAME    ", 11);
		GetFatParams (&ft); 
		*(volParams->realClusterSize) = ft.cluster_size * FormatSectorSize;

		if (volParams->bDevice && !StartFormatWriteThread())
		{
			nStatus = ERR_OS_ERROR; 
			goto error;
		}

		nStatus = FormatFat (hwndDlg, startSector, &ft, (void *) dev, cryptoInfo, volParams->quickFormat);

		if (volParams->bDevice)
			StopFormatWriteThread();

		break;

	default:
		nStatus = ERR_PARAMETER_INCORRECT; 
		goto error;
	}

	if (nStatus != ERR_SUCCESS)
		goto error;

	// Write header backup
	offset.QuadPart = volParams->hiddenVol ? volParams->hiddenVolHostSize - TC_HIDDEN_VOLUME_HEADER_OFFSET : dataAreaSize + TC_VOLUME_HEADER_GROUP_SIZE;

	if (!SetFilePointerEx ((HANDLE) dev, offset, NULL, FILE_BEGIN))
	{
		nStatus = ERR_OS_ERROR;
		goto error;
	}

	nStatus = CreateVolumeHeaderInMemory (hwndDlg, FALSE,
		header,
		volParams->ea,
		FIRST_MODE_OF_OPERATION_ID,
		volParams->password,
		volParams->pkcs5,
		volParams->pim,
		cryptoInfo->master_keydata,
		&cryptoInfo,
		dataAreaSize,
		volParams->hiddenVol ? dataAreaSize : 0,
		dataOffset,
		dataAreaSize,
		0,
		volParams->headerFlags,
		FormatSectorSize,
		FALSE);

	if (!WriteEffectiveVolumeHeader (volParams->bDevice, dev, header))
	{
		nStatus = ERR_OS_ERROR;
		goto error;
	}

	// Fill reserved header sectors (including the backup header area) with random data
	if (!volParams->hiddenVol)
	{
		nStatus = WriteRandomDataToReservedHeaderAreas (hwndDlg, dev, cryptoInfo, dataAreaSize, FALSE, FALSE);

		if (nStatus != ERR_SUCCESS)
			goto error;
	}

#ifndef DEBUG
	if (volParams->quickFormat && volParams->fileSystem != FILESYS_NTFS)
		Sleep (500);	// User-friendly GUI
#endif

error:
	dwError = GetLastError();

	burn (header, sizeof (header));
	VirtualUnlock (header, sizeof (header));

	if (dev != INVALID_HANDLE_VALUE)
	{
		if (!volParams->bDevice && !volParams->hiddenVol && nStatus != 0)
		{
			// Remove preallocated part before closing file handle if format failed
			if (SetFilePointer (dev, 0, NULL, FILE_BEGIN) == 0)
				SetEndOfFile (dev);
		}

		FlushFileBuffers (dev);

		if (bTimeStampValid)
			SetFileTime (dev, &ftCreationTime, &ftLastAccessTime, &ftLastWriteTime);

		CloseHandle (dev);
		dev = INVALID_HANDLE_VALUE;
	}

	if (nStatus != 0)
	{
		SetLastError(dwError);
		goto fv_end;
	}

	if (volParams->fileSystem == FILESYS_NTFS)
	{
		// Quick-format volume as NTFS
		int driveNo = GetLastAvailableDrive ();
		MountOptions mountOptions;
		int retCode;

		ZeroMemory (&mountOptions, sizeof (mountOptions));

		if (driveNo == -1)
		{
			if (!Silent)
			{
				MessageBoxW (volParams->hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND);
				MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);
			}

			nStatus = ERR_NO_FREE_DRIVES;
			goto fv_end;
		}

		mountOptions.ReadOnly = FALSE;
		mountOptions.Removable = FALSE;
		mountOptions.ProtectHiddenVolume = FALSE;
		mountOptions.PreserveTimestamp = bPreserveTimestamp;
		mountOptions.PartitionInInactiveSysEncScope = FALSE;
		mountOptions.UseBackupHeader = FALSE;

		if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1)
		{
			if (!Silent)
			{
				MessageBoxW (volParams->hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND);
				MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND);
			}
			nStatus = ERR_VOL_MOUNT_FAILED;
			goto fv_end;
		}

		if (!Silent && !IsAdmin () && IsUacSupported ())
			retCode = UacFormatNtfs (volParams->hwndDlg, driveNo, volParams->clusterSize);
		else
			retCode = FormatNtfs (driveNo, volParams->clusterSize);

		if (retCode != TRUE)
		{
			if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent)
				MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);

			if (dataAreaSize <= TC_MAX_FAT_SECTOR_COUNT * FormatSectorSize)
			{
				if (AskErrYesNo ("FORMAT_NTFS_FAILED_ASK_FAT", hwndDlg) == IDYES)
				{
					// NTFS format failed and the user wants to try FAT format immediately
					volParams->fileSystem = FILESYS_FAT;
					bInstantRetryOtherFilesys = TRUE;
					volParams->quickFormat = TRUE;		// Volume has already been successfully TC-formatted
					volParams->clusterSize = 0;		// Default cluster size
					goto begin_format;
				}
			}
			else
				Error ("FORMAT_NTFS_FAILED", hwndDlg);

			nStatus = ERR_DONT_REPORT;
			goto fv_end;
		}

		if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent)
			MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND);
	}

fv_end:
	dwError = GetLastError();

	if (dosDev[0])
		RemoveFakeDosName (volParams->volumePath, dosDev);

	crypto_close (cryptoInfo);

	SetLastError (dwError);
	return nStatus;
}
Exemple #17
0
void build_volumes_v2(t_volumes & volumes)
{
	HDEVINFO di = SetupDiGetClassDevs(&GUID_DEVINTERFACE_DISK, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);

	if (di != INVALID_HANDLE_VALUE)
	{
		SP_DEVINFO_DATA did;
		memset(&did, 0, sizeof(did));
		did.cbSize = sizeof(did);

		DWORD i;
		for (i=0; SetupDiEnumDeviceInfo(di, i, &did); i++)
		{
			if (did.ClassGuid == GUID_DEVCLASS_DISKDRIVE)
			{
				ULONG DevLen = 0, DevDiskLen=0;
				pfc::array_t<WCHAR> Dev, DevDisk, DevRoot;
				DEVINST pParent = NULL, ppParent = NULL;
				CM_Get_Parent_Ex(&pParent, did.DevInst, NULL, NULL);
				CM_Get_Parent_Ex(&ppParent, pParent, NULL, NULL);
				CM_Get_Device_ID_Size(&DevLen, pParent, NULL);
				CM_Get_Device_ID_Size(&DevDiskLen, did.DevInst, NULL);
				Dev.set_size(DevLen+1);
				Dev.fill_null();
				DevDisk.set_size(DevDiskLen+1);
				DevDisk.fill_null();
				CM_Get_Device_ID(pParent, Dev.get_ptr(), Dev.get_size(), NULL);
				CM_Get_Device_ID(did.DevInst, DevDisk.get_ptr(), DevDisk.get_size(), NULL);

				{
					ULONG len = 0;
					CM_Get_Device_ID_Size(&len, ppParent, NULL);
					DevRoot.set_size(len+1);
					DevRoot.fill_null();
					CM_Get_Device_ID(ppParent, DevRoot.get_ptr(), len, NULL);
				}
				bool b_shuffle;
				t_ipod_model model;
				if (g_check_devid_is_ipod(Dev.get_ptr(), model, b_shuffle))
				{
					pfc::array_t<WCHAR> DriverSymbolicPath;
					if (!wcsncmp(Dev.get_ptr(), DevRoot.get_ptr(), 7))
					{
						ULONG len=0;

						CM_Get_Device_Interface_List_Size(&len, (LPGUID)&GUID_DEVINTERFACE_USBAPPL_DEVICE, DevRoot.get_ptr(), CM_GET_DEVICE_INTERFACE_LIST_PRESENT);

						DriverSymbolicPath.set_size(len+1);
						DriverSymbolicPath.fill_null();
						CM_Get_Device_Interface_List((LPGUID)&GUID_DEVINTERFACE_USBAPPL_DEVICE, DevRoot.get_ptr(), DriverSymbolicPath.get_ptr(), len, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
						//console::formatter() << pfc::stringcvt::string_utf8_from_os(buff.get_ptr());
					}
					else
					{
						DriverSymbolicPath.set_size(1);
						DriverSymbolicPath.fill_null();
					}

					{
						ULONG DevRemovalListSize = NULL, DevBusListSize = NULL;
						pfc::array_t<WCHAR> DevRemovalList, DevBusList;
						CM_Get_Device_ID_List_Size_Ex(&DevRemovalListSize, DevDisk.get_ptr(), CM_GETIDLIST_FILTER_REMOVALRELATIONS, NULL);
						CM_Get_Device_ID_List_Size_Ex(&DevBusListSize, DevDisk.get_ptr(), CM_GETIDLIST_FILTER_BUSRELATIONS, NULL);
						DevRemovalList.set_size(DevRemovalListSize);
						DevBusList.set_size(DevBusListSize);
						CM_Get_Device_ID_List_Ex(DevDisk.get_ptr(), DevRemovalList.get_ptr(), DevRemovalListSize, CM_GETIDLIST_FILTER_REMOVALRELATIONS, NULL);
						CM_Get_Device_ID_List_Ex(DevDisk.get_ptr(), DevBusList.get_ptr(), DevBusListSize, CM_GETIDLIST_FILTER_BUSRELATIONS, NULL);
						WCHAR * ptr = DevRemovalList.get_ptr(), *pvolume=NULL;
						{
							t_size ptrlen= NULL;
							while (ptr && (ptrlen = wcslen(ptr)))
							{
								if (!wcsicmp_partial(ptr, L"STORAGE\\"))
								{
									pvolume = ptr;
									break;
								}
								ptr+=ptrlen;
								ptr++;
							}
						}

						if (!pvolume)
						{
							ptr = DevBusList.get_ptr();
							t_size ptrlen= NULL;
							while (ptr && (ptrlen = wcslen(ptr)))
							{
								if (!wcsicmp_partial(ptr, L"STORAGE\\"))
								{
									pvolume = ptr;
									break;
								}
								ptr+=ptrlen;
								ptr++;
							}
						}

						if (pvolume)
						{
							SP_DEVINFO_DATA pdid;
							memset(&pdid, 0, sizeof(pdid));
							pdid.cbSize = sizeof(pdid);
							HDEVINFO pdi = SetupDiGetClassDevs(&GUID_DEVINTERFACE_VOLUME, NULL, NULL, DIGCF_PRESENT|DIGCF_DEVICEINTERFACE);;
							SetupDiOpenDeviceInfo(pdi, pvolume, NULL, NULL, &pdid);
							{
								{
									DWORD j;
									SP_DEVICE_INTERFACE_DATA dia;
									memset(&dia, 0, sizeof(dia));
									dia.cbSize = sizeof(dia);
									for (j=0; SetupDiEnumDeviceInterfaces(pdi, &pdid, &GUID_DEVINTERFACE_VOLUME, j, &dia); j++)
									{
										DWORD required_size = 0;

										pfc::array_t<t_uint8> data;

										SetupDiGetDeviceInterfaceDetail(pdi, &dia, NULL, NULL, &required_size, &pdid);
										data.set_size(required_size);
										data.fill_null();
										if (required_size >= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA))
										{
											SP_DEVICE_INTERFACE_DETAIL_DATA * didd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)data.get_ptr();
											didd->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
											if (SetupDiGetDeviceInterfaceDetail(pdi, &dia, didd, required_size, NULL, &pdid))
											{

												pfc::array_t<WCHAR> path;
												t_size len = wcslen(didd->DevicePath);
												path.append_fromptr(didd->DevicePath, len);
												path.grow_size (len + sizeof(WCHAR)*2);
												path[len] = '\\';
												path[len+1] = 0;

												WCHAR volumename[129];
												memset(&volumename, 0, sizeof(volumename));
												if (GetVolumeNameForVolumeMountPoint(path.get_ptr(), volumename, 128))
												{
													volumes.add_item(t_volume(volumename, Dev.get_ptr(), model, b_shuffle, pParent, DriverSymbolicPath.get_ptr()));
												}
											}
										}
									}
								}
							}
							SetupDiDestroyDeviceInfoList(pdi);
						}
					}

				}
			}
		}

		SetupDiDestroyDeviceInfoList(di);
	}
}