Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1205 lines
36 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. mountie.c
  5. Abstract:
  6. Abstract
  7. Author:
  8. Rod Gamache (rodga) 4-Mar-1998
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include <nt.h>
  14. #include <ntdef.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <devioctl.h>
  19. //#include <ntdddisk.h>
  20. //#include <ntddscsi.h>
  21. #include <stdio.h>
  22. #include <stddef.h>
  23. #include <stdlib.h>
  24. #include <cfgmgr32.h>
  25. #include <mountmgr.h>
  26. #include "disksp.h"
  27. #include "mountie.h"
  28. #include <strsafe.h> // Should be included last.
  29. #define OUTPUT_BUFFER_LEN 1024
  30. /*
  31. * DevfileOpen - open a device file given a pathname
  32. *
  33. * Return a non-zero code for error.
  34. */
  35. DWORD
  36. DevfileOpen(
  37. OUT HANDLE *Handle,
  38. IN wchar_t *pathname
  39. )
  40. {
  41. HANDLE fh;
  42. OBJECT_ATTRIBUTES objattrs;
  43. UNICODE_STRING cwspath;
  44. NTSTATUS status;
  45. IO_STATUS_BLOCK iostatus;
  46. RtlInitUnicodeString(&cwspath, pathname);
  47. InitializeObjectAttributes(&objattrs, &cwspath, OBJ_CASE_INSENSITIVE,
  48. NULL, NULL);
  49. fh = NULL;
  50. status = NtOpenFile(&fh,
  51. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  52. &objattrs, &iostatus,
  53. FILE_SHARE_READ | FILE_SHARE_WRITE,
  54. FILE_SYNCHRONOUS_IO_ALERT);
  55. if (status != STATUS_SUCCESS) {
  56. return status;
  57. }
  58. if (iostatus.Status != STATUS_SUCCESS) {
  59. if (fh) {
  60. NtClose(fh);
  61. }
  62. return iostatus.Status;
  63. }
  64. *Handle = fh;
  65. return STATUS_SUCCESS;
  66. } // DevfileOpen
  67. /*
  68. * DevfileClose - close a file
  69. */
  70. VOID
  71. DevfileClose(
  72. IN HANDLE Handle
  73. )
  74. {
  75. NtClose(Handle);
  76. } // DevFileClose
  77. /*
  78. * DevfileIoctl - issue an ioctl to a device
  79. */
  80. DWORD
  81. DevfileIoctl(
  82. IN HANDLE Handle,
  83. IN DWORD Ioctl,
  84. IN PVOID InBuf,
  85. IN ULONG InBufSize,
  86. IN OUT PVOID OutBuf,
  87. IN DWORD OutBufSize,
  88. OUT LPDWORD returnLength
  89. )
  90. {
  91. NTSTATUS status;
  92. IO_STATUS_BLOCK ioStatus;
  93. status = NtDeviceIoControlFile(Handle,
  94. (HANDLE) NULL,
  95. (PIO_APC_ROUTINE) NULL,
  96. NULL,
  97. &ioStatus,
  98. Ioctl,
  99. InBuf, InBufSize,
  100. OutBuf, OutBufSize);
  101. if ( status == STATUS_PENDING ) {
  102. status = NtWaitForSingleObject( Handle, FALSE, NULL );
  103. }
  104. if ( NT_SUCCESS(status) ) {
  105. status = ioStatus.Status;
  106. }
  107. if ( ARGUMENT_PRESENT(returnLength) ) {
  108. *returnLength = (DWORD)ioStatus.Information;
  109. }
  110. return status;
  111. } // DevfileIoctl
  112. DWORD
  113. DisksAssignDosDevice(
  114. PCHAR MountName,
  115. PWCHAR VolumeDevName
  116. )
  117. /*++
  118. Routine Description:
  119. Inputs:
  120. MountName -
  121. VolumeDevName -
  122. Return value:
  123. A Win32 error code.
  124. --*/
  125. {
  126. WCHAR mount_device[MAX_PATH];
  127. USHORT mount_point_len;
  128. USHORT dev_name_len;
  129. HANDLE handle;
  130. DWORD status;
  131. USHORT inputlength;
  132. PMOUNTMGR_CREATE_POINT_INPUT input;
  133. status = DevfileOpen(&handle, MOUNTMGR_DEVICE_NAME);
  134. if (status) {
  135. return status;
  136. }
  137. if ( FAILED( StringCchPrintfW( mount_device,
  138. RTL_NUMBER_OF(mount_device) - 1,
  139. L"\\DosDevices\\%S",
  140. MountName ) ) ) {
  141. return ERROR_NOT_ENOUGH_MEMORY;
  142. }
  143. mount_point_len = wcslen(mount_device) * sizeof(WCHAR);
  144. dev_name_len = wcslen(VolumeDevName) * sizeof(WCHAR);
  145. inputlength = sizeof(MOUNTMGR_CREATE_POINT_INPUT) +
  146. mount_point_len + dev_name_len;
  147. input = (PMOUNTMGR_CREATE_POINT_INPUT)malloc(inputlength);
  148. if (!input) {
  149. DevfileClose(handle);
  150. return ERROR_NOT_ENOUGH_MEMORY;
  151. }
  152. input->SymbolicLinkNameOffset = sizeof(MOUNTMGR_CREATE_POINT_INPUT);
  153. input->SymbolicLinkNameLength = mount_point_len;
  154. input->DeviceNameOffset = input->SymbolicLinkNameOffset +
  155. input->SymbolicLinkNameLength;
  156. input->DeviceNameLength = dev_name_len;
  157. RtlCopyMemory((PCHAR)input + input->SymbolicLinkNameOffset,
  158. mount_device, mount_point_len);
  159. RtlCopyMemory((PCHAR)input + input->DeviceNameOffset,
  160. VolumeDevName, dev_name_len);
  161. status = DevfileIoctl(handle, IOCTL_MOUNTMGR_CREATE_POINT,
  162. input, inputlength, NULL, 0, NULL);
  163. free(input);
  164. DevfileClose(handle);
  165. return status;
  166. } // DisksAssignDosDevice
  167. DWORD
  168. DisksRemoveDosDevice(
  169. PCHAR MountName
  170. )
  171. /*++
  172. Routine Description:
  173. Inputs:
  174. MountName -
  175. Return value:
  176. --*/
  177. {
  178. WCHAR mount_device[MAX_PATH];
  179. USHORT mount_point_len;
  180. USHORT dev_name_len;
  181. HANDLE handle;
  182. DWORD status;
  183. USHORT inputlength;
  184. PMOUNTMGR_MOUNT_POINT input;
  185. UCHAR bogusBuffer[128];
  186. status = DevfileOpen(&handle, MOUNTMGR_DEVICE_NAME);
  187. if (status) {
  188. return status;
  189. }
  190. if ( FAILED( StringCchPrintfW( mount_device,
  191. RTL_NUMBER_OF(mount_device) - 1,
  192. L"\\DosDevices\\%S",
  193. MountName ) ) ) {
  194. return ERROR_NOT_ENOUGH_MEMORY;
  195. }
  196. mount_point_len = wcslen(mount_device) * sizeof(WCHAR);
  197. inputlength = sizeof(MOUNTMGR_MOUNT_POINT) + mount_point_len;
  198. input = (PMOUNTMGR_MOUNT_POINT)malloc(inputlength);
  199. if (!input) {
  200. DevfileClose(handle);
  201. return ERROR_NOT_ENOUGH_MEMORY;
  202. }
  203. input->UniqueIdOffset = 0;
  204. input->UniqueIdLength = 0;
  205. input->DeviceNameOffset = 0;
  206. input->DeviceNameLength = 0;
  207. input->SymbolicLinkNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
  208. input->SymbolicLinkNameLength = mount_point_len;
  209. RtlCopyMemory((PCHAR)input + input->SymbolicLinkNameOffset,
  210. mount_device, mount_point_len);
  211. status = DevfileIoctl(handle, IOCTL_MOUNTMGR_DELETE_POINTS,
  212. input, inputlength, bogusBuffer, 128, NULL);
  213. free(input);
  214. DevfileClose(handle);
  215. return status;
  216. } // DisksRemoveDosDevice
  217. DWORD
  218. FindFirstVolumeForSignature(
  219. IN HANDLE MountMgrHandle,
  220. IN DWORD Signature,
  221. OUT LPSTR VolumeName,
  222. IN DWORD BufferLength,
  223. OUT LPHANDLE Handle,
  224. OUT PVOID UniqueId OPTIONAL,
  225. IN OUT LPDWORD IdLength,
  226. OUT PUCHAR DriveLetter OPTIONAL
  227. )
  228. /*++
  229. Inputs:
  230. MountMgrHandle - a handle to the mount manager.
  231. Signature - the signature we are looking for.
  232. VolumeName - must be a valid buffer of at least MAX_PATH characters.
  233. BufferLength - the length of VolumeName.
  234. Handle - pointer to receive the FindFirstVolume/FindNextVolume enum handle.
  235. UniqueId - optional pointer to buffer to receive the UniqueId.
  236. IdLength - pointer to length of the UniqueId buffer. Must be valid if
  237. UniqueId is present.
  238. DriveLetter - returns the drive letter if present.
  239. Return Value:
  240. Win32 error code
  241. --*/
  242. {
  243. HANDLE handle;
  244. BOOL success;
  245. DWORD status;
  246. LPDWORD idSignature;
  247. DWORD bufLength;
  248. LPWSTR wVolumeName;
  249. DWORD inputlength;
  250. DWORD outputlength;
  251. DWORD returnlength;
  252. UCHAR outputBuffer[OUTPUT_BUFFER_LEN];
  253. PMOUNTMGR_MOUNT_POINT input;
  254. PMOUNTMGR_MOUNT_POINTS output;
  255. PUCHAR byteBuffer;
  256. DWORD mountPoints;
  257. if ( !ARGUMENT_PRESENT( VolumeName ) ) {
  258. return ERROR_INVALID_PARAMETER;
  259. }
  260. handle = FindFirstVolume( VolumeName, BufferLength );
  261. if ( handle == INVALID_HANDLE_VALUE ) {
  262. return(ERROR_FILE_NOT_FOUND);
  263. }
  264. do {
  265. bufLength = strlen( VolumeName );
  266. VolumeName[bufLength-1] = '\0';
  267. if ( VolumeName[1] != '\\' ) {
  268. status = ERROR_INVALID_NAME;
  269. break;
  270. } else {
  271. VolumeName[1] = '?';
  272. wVolumeName = malloc( bufLength * sizeof(WCHAR) );
  273. if (!wVolumeName) {
  274. status = ERROR_NOT_ENOUGH_MEMORY;
  275. break;
  276. }
  277. mbstowcs( wVolumeName, VolumeName, bufLength );
  278. bufLength--;
  279. printf( "\nFound volume %ws\n", wVolumeName );
  280. inputlength = sizeof(MOUNTMGR_MOUNT_POINT) +
  281. (bufLength*sizeof(WCHAR)) + (2*sizeof(WCHAR));
  282. input = (PMOUNTMGR_MOUNT_POINT)malloc(inputlength);
  283. if (!input) {
  284. free( wVolumeName );
  285. status = ERROR_NOT_ENOUGH_MEMORY;
  286. break;
  287. }
  288. input->SymbolicLinkNameOffset = 0;
  289. input->SymbolicLinkNameLength = 0;
  290. input->UniqueIdOffset = 0;
  291. input->UniqueIdLength = 0;
  292. input->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
  293. input->DeviceNameLength = (USHORT)(bufLength * sizeof(WCHAR));
  294. RtlCopyMemory((PCHAR)input + input->DeviceNameOffset,
  295. wVolumeName, bufLength * sizeof(WCHAR) );
  296. outputlength = OUTPUT_BUFFER_LEN;
  297. status = DevfileIoctl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
  298. input, inputlength, outputBuffer, outputlength, &returnlength);
  299. if ( status != ERROR_SUCCESS ) {
  300. // Cast as the data is actually a wide string.
  301. printf( "Query points for %ws failed, error %u\n",
  302. (PWCHAR)((PCHAR)input + input->DeviceNameOffset),
  303. status );
  304. free( wVolumeName );
  305. free(input);
  306. wVolumeName = NULL;
  307. input = NULL;
  308. break;
  309. } else {
  310. output = (PMOUNTMGR_MOUNT_POINTS)outputBuffer;
  311. mountPoints = output->NumberOfMountPoints;
  312. if ( !mountPoints ) {
  313. return ERROR_INVALID_DATA;
  314. }
  315. byteBuffer = outputBuffer + output->MountPoints[0].UniqueIdOffset;
  316. idSignature = (LPDWORD)byteBuffer;
  317. if ( !Signature ||
  318. (Signature == *idSignature) ) {
  319. NTSTATUS ntStatus;
  320. UNICODE_STRING unicodeString;
  321. OEM_STRING oemString;
  322. DWORD count;
  323. UCHAR driveLetter;
  324. UCHAR devName[ MAX_PATH ];
  325. PWCHAR wideBuffer;
  326. LPDWORD dwordBuffer;
  327. free( wVolumeName );
  328. free(input);
  329. input = NULL;
  330. wVolumeName = NULL;
  331. *Handle = handle;
  332. if ( ARGUMENT_PRESENT(UniqueId) ) {
  333. if ( *IdLength > output->MountPoints[0].UniqueIdLength ) {
  334. *IdLength = output->MountPoints[0].UniqueIdLength;
  335. }
  336. RtlCopyMemory( UniqueId, byteBuffer, *IdLength );
  337. }
  338. //
  339. // Print the ID
  340. //
  341. count = output->MountPoints[0].UniqueIdLength;
  342. count = (count + 3) / 4;
  343. dwordBuffer = (LPDWORD)(outputBuffer + output->MountPoints[0].UniqueIdOffset);
  344. printf( "Id = " );
  345. while ( count-- ) {
  346. printf( "%08lx ", *(dwordBuffer++) );
  347. }
  348. printf( "\n" );
  349. if ( ARGUMENT_PRESENT(DriveLetter) ) {
  350. *DriveLetter = 0;
  351. while ( mountPoints-- ) {
  352. byteBuffer = outputBuffer +
  353. output->MountPoints[mountPoints].SymbolicLinkNameOffset;
  354. //
  355. // Covert UNICODE name to OEM string upper case
  356. //
  357. unicodeString.Buffer = (PWCHAR)byteBuffer;
  358. unicodeString.MaximumLength = output->MountPoints[mountPoints].SymbolicLinkNameLength + sizeof(WCHAR);
  359. unicodeString.Length = output->MountPoints[mountPoints].SymbolicLinkNameLength;
  360. oemString.Buffer = devName;
  361. oemString.MaximumLength = sizeof(devName);
  362. ntStatus = RtlUpcaseUnicodeStringToOemString(
  363. &oemString,
  364. &unicodeString,
  365. FALSE );
  366. if ( ntStatus != STATUS_SUCCESS ) {
  367. status = RtlNtStatusToDosError( ntStatus );
  368. return status;
  369. }
  370. devName[oemString.Length] = '\0';
  371. count = sscanf( devName, "\\DOSDEVICES\\%c:", &driveLetter );
  372. wideBuffer = (PWCHAR)byteBuffer;
  373. wideBuffer[(output->MountPoints[mountPoints].SymbolicLinkNameLength)/2] = L'\0';
  374. if ( count ) {
  375. *DriveLetter = driveLetter;
  376. // Cast as the data is actually a wide string.
  377. printf( "Symbolic name = %ws, letter = %c:\\\n",
  378. (PWCHAR)byteBuffer,
  379. driveLetter );
  380. if ( Signature ) {
  381. break;
  382. }
  383. } else {
  384. // Cast as the data is actually a wide string.
  385. printf( "Symbolic name = %ws\n",
  386. (PWCHAR)byteBuffer );
  387. }
  388. }
  389. }
  390. if ( Signature ) {
  391. return ERROR_SUCCESS;
  392. }
  393. }
  394. }
  395. free(wVolumeName);
  396. free(input);
  397. }
  398. success = FindNextVolume( handle,
  399. VolumeName,
  400. BufferLength );
  401. if ( !success ) {
  402. status = GetLastError();
  403. }
  404. } while ( status == ERROR_SUCCESS );
  405. FindVolumeClose( handle );
  406. return status;
  407. } // FindFirstVolumeForSignature
  408. DWORD
  409. FindNextVolumeForSignature(
  410. IN HANDLE MountMgrHandle,
  411. IN DWORD Signature,
  412. IN HANDLE Handle,
  413. OUT LPSTR VolumeName,
  414. IN DWORD BufferLength,
  415. OUT PVOID UniqueId OPTIONAL,
  416. IN OUT LPDWORD IdLength,
  417. OUT PUCHAR DriveLetter OPTIONAL
  418. )
  419. /*++
  420. Inputs:
  421. MountMgrHandle - a handle to the mount manager.
  422. Signature - the signature we are looking for.
  423. Handle - the FindFirstVolume/FindNextVolume enum handle.
  424. VolumeName - must be a valid buffer of at least MAX_PATH characters.
  425. BufferLength - the length of VolumeName.
  426. UniqueId - optional pointer to buffer to receive the UniqueId.
  427. IdLength - point to the length of the UniqueId buffer.
  428. DriveLetter - returns the drive letter if present.
  429. Return Value:
  430. Win32 error code
  431. --*/
  432. {
  433. BOOL success;
  434. DWORD status;
  435. LPDWORD idSignature;
  436. DWORD bufLength;
  437. LPWSTR wVolumeName;
  438. DWORD inputlength;
  439. DWORD outputlength;
  440. DWORD returnlength;
  441. UCHAR outputBuffer[OUTPUT_BUFFER_LEN];
  442. PMOUNTMGR_MOUNT_POINT input;
  443. PMOUNTMGR_MOUNT_POINTS output;
  444. PUCHAR byteBuffer;
  445. DWORD mountPoints;
  446. if ( !ARGUMENT_PRESENT( VolumeName ) ) {
  447. return ERROR_INVALID_PARAMETER;
  448. }
  449. do {
  450. success = FindNextVolume( Handle, VolumeName, BufferLength );
  451. if ( !success ) {
  452. status = GetLastError();
  453. break;
  454. }
  455. bufLength = strlen( VolumeName );
  456. VolumeName[bufLength-1] = '\0';
  457. if ( VolumeName[1] != '\\' ) {
  458. status = ERROR_INVALID_NAME;
  459. break;
  460. } else {
  461. VolumeName[1] = '?';
  462. bufLength--;
  463. wVolumeName = malloc( bufLength * sizeof(WCHAR) );
  464. if (!wVolumeName) {
  465. status = ERROR_NOT_ENOUGH_MEMORY;
  466. break;
  467. }
  468. mbstowcs( wVolumeName, VolumeName, bufLength );
  469. inputlength = sizeof(MOUNTMGR_MOUNT_POINT) +
  470. (bufLength*sizeof(WCHAR)) + (2*sizeof(WCHAR));
  471. input = (PMOUNTMGR_MOUNT_POINT)malloc(inputlength);
  472. if (!input) {
  473. free( wVolumeName );
  474. status = ERROR_NOT_ENOUGH_MEMORY;
  475. break;
  476. }
  477. input->SymbolicLinkNameOffset = 0;
  478. input->SymbolicLinkNameLength = 0;
  479. input->UniqueIdOffset = 0;
  480. input->UniqueIdLength = 0;
  481. input->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
  482. input->DeviceNameLength = (USHORT)(bufLength * sizeof(WCHAR));
  483. RtlCopyMemory((PCHAR)input + input->DeviceNameOffset,
  484. wVolumeName, bufLength * sizeof(WCHAR) );
  485. outputlength = OUTPUT_BUFFER_LEN;
  486. status = DevfileIoctl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
  487. input, inputlength, outputBuffer, outputlength, &returnlength);
  488. if ( status != ERROR_SUCCESS ) {
  489. free( wVolumeName );
  490. free(input);
  491. break;
  492. } else {
  493. output = (PMOUNTMGR_MOUNT_POINTS)outputBuffer;
  494. mountPoints = output->NumberOfMountPoints;
  495. if ( !mountPoints ) {
  496. return ERROR_INVALID_DATA;
  497. }
  498. byteBuffer = outputBuffer + output->MountPoints[0].UniqueIdOffset;
  499. idSignature = (LPDWORD)byteBuffer;
  500. if ( Signature == *idSignature ) {
  501. NTSTATUS ntStatus;
  502. UNICODE_STRING unicodeString;
  503. OEM_STRING oemString;
  504. DWORD count;
  505. UCHAR driveLetter;
  506. UCHAR devName[ MAX_PATH ];
  507. free( wVolumeName );
  508. free(input);
  509. if ( ARGUMENT_PRESENT(UniqueId) ) {
  510. if ( *IdLength > output->MountPoints[0].UniqueIdLength ) {
  511. *IdLength = output->MountPoints[0].UniqueIdLength;
  512. }
  513. RtlCopyMemory( UniqueId, byteBuffer, *IdLength );
  514. }
  515. if ( ARGUMENT_PRESENT(DriveLetter) ) {
  516. *DriveLetter = 0;
  517. while ( mountPoints-- ) {
  518. byteBuffer = outputBuffer +
  519. output->MountPoints[mountPoints].SymbolicLinkNameOffset;
  520. //
  521. // Covert UNICODE name to OEM string upper case
  522. //
  523. unicodeString.Buffer = (PWCHAR)byteBuffer;
  524. unicodeString.MaximumLength = output->MountPoints[mountPoints].SymbolicLinkNameLength + sizeof(WCHAR);
  525. unicodeString.Length = output->MountPoints[mountPoints].SymbolicLinkNameLength;
  526. oemString.Buffer = devName;
  527. oemString.MaximumLength = sizeof(devName);
  528. ntStatus = RtlUpcaseUnicodeStringToOemString(
  529. &oemString,
  530. &unicodeString,
  531. FALSE );
  532. if ( ntStatus != STATUS_SUCCESS ) {
  533. status = RtlNtStatusToDosError( ntStatus );
  534. return status;
  535. }
  536. devName[oemString.Length] = '\0';
  537. count = sscanf( devName, "\\DOSDEVICES\\%c:", &driveLetter );
  538. if ( count ) {
  539. *DriveLetter = driveLetter;
  540. break;
  541. }
  542. }
  543. }
  544. return ERROR_SUCCESS;
  545. }
  546. }
  547. free(wVolumeName);
  548. free(input);
  549. }
  550. success = FindNextVolume( Handle,
  551. VolumeName,
  552. BufferLength );
  553. if ( !success ) {
  554. status = GetLastError();
  555. }
  556. } while ( status == ERROR_SUCCESS );
  557. return status;
  558. } // FindNextVolumeForSignature
  559. #if 0
  560. DWORD
  561. DisksSetDiskInfo(
  562. IN HKEY RegistryKey,
  563. IN DWORD Signature
  564. )
  565. /*++
  566. Inputs:
  567. Return Value:
  568. A Win32 error code.
  569. --*/
  570. {
  571. DWORD status;
  572. UCHAR driveLetter;
  573. UCHAR volumeName[MAX_PATH];
  574. HANDLE handle;
  575. HANDLE mHandle;
  576. UCHAR uniqueId[MAX_PATH];
  577. UCHAR smashedId[MAX_PATH+1];
  578. DWORD idLength;
  579. DWORD i;
  580. WCHAR indexName[16];
  581. HKEY registryKey;
  582. DWORD disposition;
  583. status = DevfileOpen( &mHandle, MOUNTMGR_DEVICE_NAME );
  584. if ( status != ERROR_SUCCESS ) {
  585. printf( "SetDiskInfo: DevfileOpen failed, status = %u\n", status);
  586. return status;
  587. }
  588. status = ClusterRegDeleteKey( RegistryKey, L"MountMgr" );
  589. if ( (status != ERROR_SUCCESS) && (status != ERROR_FILE_NOT_FOUND) ) {
  590. DevfileClose( mHandle );
  591. printf( "DiskInfo: ClusterRegDeleteKey failed, status = %1!u!\n", status);
  592. return status;
  593. }
  594. status = ClusterRegCreateKey( RegistryKey,
  595. L"MountMgr",
  596. 0,
  597. KEY_READ | KEY_WRITE,
  598. NULL,
  599. &registryKey,
  600. &disposition );
  601. if ( status != ERROR_SUCCESS ) {
  602. DevfileClose( mHandle );
  603. (DiskpLogEvent)(
  604. ResourceHandle,
  605. LOG_ERROR,
  606. L"SetDiskInfo: ClusterRegCreateKey failed, status = %1!u!\n", status);
  607. return status;
  608. }
  609. idLength = MAX_PATH;
  610. status = FindFirstVolumeForSignature( ResourceHandle,
  611. mHandle,
  612. Signature,
  613. volumeName,
  614. MAX_PATH,
  615. &handle,
  616. uniqueId,
  617. &idLength,
  618. &driveLetter );
  619. if ( status != ERROR_SUCCESS ) {
  620. DevfileClose( mHandle );
  621. ClusterRegCloseKey( registryKey );
  622. (DiskpLogEvent)(
  623. ResourceHandle,
  624. LOG_ERROR,
  625. L"SetDiskInfo: FindFirstVolume failed, status = %1!u!\n", status);
  626. return status;
  627. }
  628. i = 0;
  629. while ( status == ERROR_SUCCESS ) {
  630. wsprintfW( indexName, L"%0.5u", i++ );
  631. smashedId[0] = driveLetter;
  632. RtlCopyMemory( &smashedId[1], uniqueId, idLength );
  633. status = ClusterRegSetValue( registryKey,
  634. indexName,
  635. REG_BINARY,
  636. (CONST BYTE *)smashedId,
  637. idLength + 1);
  638. if ( status != ERROR_SUCCESS ) {
  639. //printf("DiskSetDiskInfo, error setting value %s\n", indexName );
  640. }
  641. idLength = MAX_PATH;
  642. status = FindNextVolumeForSignature( mHandle,
  643. Signature,
  644. handle,
  645. volumeName,
  646. MAX_PATH,
  647. uniqueId,
  648. &idLength,
  649. &driveLetter );
  650. }
  651. FindVolumeClose( handle );
  652. DevfileClose( mHandle );
  653. ClusterRegCloseKey( registryKey );
  654. return ERROR_SUCCESS;
  655. } // DisksSetDiskInfo
  656. DWORD
  657. DisksSetMountMgr(
  658. IN HKEY RegistryKey,
  659. IN DWORD Signature
  660. )
  661. /*++
  662. Inputs:
  663. Return Value:
  664. A Win32 error code.
  665. --*/
  666. {
  667. DWORD status;
  668. UCHAR volumeName[MAX_PATH];
  669. LPWSTR wVolumeName;
  670. HANDLE mHandle;
  671. HANDLE handle = NULL;
  672. UCHAR storedId[MAX_PATH+1];
  673. DWORD storedIdSize;
  674. DWORD i;
  675. WCHAR indexName[16];
  676. HKEY registryKey;
  677. DWORD type;
  678. DWORD bufLength;
  679. UCHAR driveLetter[4];
  680. NTSTATUS ntStatus;
  681. status = DevfileOpen( &mHandle, MOUNTMGR_DEVICE_NAME );
  682. if ( status != ERROR_SUCCESS ) {
  683. (DiskpLogEvent)(
  684. ResourceHandle,
  685. LOG_ERROR,
  686. L"SetMountMgr: DevfileOpen failed, status = %1!u!\n", status);
  687. return status;
  688. }
  689. status = ClusterRegOpenKey( RegistryKey,
  690. L"MountMgr",
  691. KEY_READ | KEY_WRITE,
  692. &registryKey );
  693. if ( status != ERROR_SUCCESS ) {
  694. DevfileClose( mHandle );
  695. return status;
  696. (DiskpLogEvent)(
  697. ResourceHandle,
  698. LOG_ERROR,
  699. L"SetMountMgr: ClusterRegOpenKey failed, status = %1!u!\n", status);
  700. }
  701. i = 0;
  702. do {
  703. wsprintfW( indexName, L"%0.5u", i++ );
  704. storedIdSize = MAX_PATH;
  705. status = ClusterRegQueryValue( registryKey,
  706. indexName,
  707. &type,
  708. (PUCHAR)storedId,
  709. &storedIdSize);
  710. (DiskpLogEvent)(
  711. ResourceHandle,
  712. LOG_ERROR,
  713. L"SetMountMgr: ClusterRegQueryValue returned status = %1!u!\n", status);
  714. if ( status != ERROR_SUCCESS ) {
  715. break;
  716. }
  717. storedId[1] = ':';
  718. storedId[2] = '\0';
  719. ntStatus = DisksRemoveDosDevice( storedId );
  720. status = RtlNtStatusToDosError( ntStatus );
  721. (DiskpLogEvent)(
  722. ResourceHandle,
  723. LOG_ERROR,
  724. L"SetMountMgr: RemoveDosDevice for %1!x! returned status = %2!u!\n", *storedId, status);
  725. if ( status == ERROR_FILE_NOT_FOUND ) {
  726. status = ERROR_SUCCESS;
  727. }
  728. } while ( status == ERROR_SUCCESS );
  729. status = FindFirstVolumeForSignature( ResourceHandle,
  730. mHandle,
  731. Signature,
  732. volumeName,
  733. MAX_PATH,
  734. &handle,
  735. NULL,
  736. NULL,
  737. &driveLetter[0] );
  738. if ( status != ERROR_SUCCESS ) {
  739. (DiskpLogEvent)(
  740. ResourceHandle,
  741. LOG_ERROR,
  742. L"SetMountMgr: FindFirstVolume failed for Signature %1!08lx!, status = %2!u!\n", Signature, status);
  743. }
  744. i = 0;
  745. while ( status == ERROR_SUCCESS ) {
  746. wsprintfW( indexName, L"%0.5u", i++ );
  747. storedIdSize = MAX_PATH;
  748. status = ClusterRegQueryValue( registryKey,
  749. indexName,
  750. &type,
  751. (PUCHAR)storedId,
  752. &storedIdSize );
  753. if ( status != ERROR_SUCCESS ) {
  754. break;
  755. }
  756. //
  757. // Remove current drive letter
  758. //
  759. driveLetter[1] = ':';
  760. driveLetter[2] = '\0';
  761. ntStatus = DisksRemoveDosDevice( driveLetter );
  762. status = RtlNtStatusToDosError( ntStatus );
  763. (DiskpLogEvent)(
  764. ResourceHandle,
  765. LOG_ERROR,
  766. L"SetMountMgr: RemoveDosDevice for %1!x! returned status = %2!u!\n", driveLetter[0], status);
  767. bufLength = strlen( volumeName );
  768. wVolumeName = malloc( (bufLength + 1) * sizeof(WCHAR) );
  769. if (!wVolumeName) {
  770. status = ERROR_NOT_ENOUGH_MEMORY;
  771. break;
  772. }
  773. mbstowcs( wVolumeName, volumeName, bufLength + 1 );
  774. storedId[1] = ':';
  775. storedId[2] = '\0';
  776. status = DisksAssignDosDevice( storedId, wVolumeName );
  777. (DiskpLogEvent)(
  778. ResourceHandle,
  779. LOG_ERROR,
  780. L"SetMountMgr: AssignDosDevice for %1!x! (%2!ws!) returned status = %3!u!\n", *storedId, wVolumeName, status);
  781. free( wVolumeName );
  782. if ( status != ERROR_SUCCESS ) {
  783. break;
  784. }
  785. status = FindNextVolumeForSignature( mHandle,
  786. Signature,
  787. handle,
  788. volumeName,
  789. MAX_PATH,
  790. NULL,
  791. NULL,
  792. &driveLetter[0] );
  793. if ( status != ERROR_SUCCESS ) {
  794. (DiskpLogEvent)(
  795. ResourceHandle,
  796. LOG_ERROR,
  797. L"SetMountMgr: FindNextVolume failed, status = %1!u!\n", status);
  798. }
  799. if ( status == ERROR_NO_MORE_FILES ) {
  800. status = ERROR_SUCCESS;
  801. break;
  802. }
  803. }
  804. DevfileClose( mHandle );
  805. ClusterRegCloseKey( registryKey );
  806. if ( handle ) {
  807. FindVolumeClose( handle );
  808. }
  809. return status;
  810. } // DisksSetMountMgr
  811. BOOL
  812. DisksDoesDiskInfoMatch(
  813. IN HKEY RegistryKey,
  814. IN DWORD Signature
  815. )
  816. /*++
  817. Inputs:
  818. Return Value:
  819. A Win32 error code.
  820. --*/
  821. {
  822. DWORD status;
  823. UCHAR driveLetter;
  824. UCHAR volumeName[MAX_PATH];
  825. HANDLE handle;
  826. HANDLE mHandle;
  827. UCHAR uniqueId[MAX_PATH];
  828. UCHAR smashedId[MAX_PATH+1];
  829. UCHAR storedId[MAX_PATH+1];
  830. DWORD idLength;
  831. DWORD storedIdSize;
  832. DWORD i;
  833. WCHAR indexName[16];
  834. HKEY registryKey;
  835. DWORD type;
  836. status = DevfileOpen( &mHandle, MOUNTMGR_DEVICE_NAME );
  837. if ( status != ERROR_SUCCESS ) {
  838. return FALSE;
  839. }
  840. status = ClusterRegOpenKey( RegistryKey,
  841. L"MountMgr",
  842. KEY_READ | KEY_WRITE,
  843. &registryKey );
  844. if ( status != ERROR_SUCCESS ) {
  845. DevfileClose( mHandle );
  846. return FALSE;
  847. }
  848. idLength = MAX_PATH;
  849. status = FindFirstVolumeForSignature( ResourceHandle,
  850. mHandle,
  851. Signature,
  852. volumeName,
  853. MAX_PATH,
  854. &handle,
  855. uniqueId,
  856. &idLength,
  857. &driveLetter );
  858. if ( status != ERROR_SUCCESS ) {
  859. DevfileClose( mHandle );
  860. ClusterRegCloseKey( registryKey );
  861. return FALSE;
  862. }
  863. i = 0;
  864. while ( status == ERROR_SUCCESS ) {
  865. wsprintfW( indexName, L"%0.5u", i++ );
  866. smashedId[0] = driveLetter;
  867. RtlCopyMemory( &smashedId[1], uniqueId, idLength );
  868. storedIdSize = MAX_PATH;
  869. status = ClusterRegQueryValue( registryKey,
  870. indexName,
  871. &type,
  872. (PUCHAR)storedId,
  873. &storedIdSize);
  874. if ( (status != ERROR_SUCCESS) ||
  875. (type != REG_BINARY) ||
  876. (storedIdSize != (idLength+1)) ||
  877. (RtlCompareMemory( smashedId, storedId, idLength ) != idLength) ) {
  878. FindVolumeClose( handle );
  879. DevfileClose( mHandle );
  880. ClusterRegCloseKey( registryKey );
  881. return FALSE;
  882. }
  883. idLength = MAX_PATH;
  884. status = FindNextVolumeForSignature( mHandle,
  885. Signature,
  886. handle,
  887. volumeName,
  888. MAX_PATH,
  889. uniqueId,
  890. &idLength,
  891. &driveLetter );
  892. }
  893. FindVolumeClose( handle );
  894. DevfileClose( mHandle );
  895. ClusterRegCloseKey( registryKey );
  896. if ( status != ERROR_NO_MORE_FILES ) {
  897. return FALSE;
  898. }
  899. return TRUE;
  900. } // DisksDoesDiskInfoMatch
  901. BOOL
  902. DisksIsDiskInfoValid(
  903. IN HKEY RegistryKey,
  904. IN DWORD Signature
  905. )
  906. /*++
  907. Inputs:
  908. Return Value:
  909. A Win32 error code.
  910. --*/
  911. {
  912. DWORD status;
  913. UCHAR volumeName[MAX_PATH];
  914. UCHAR storedId[MAX_PATH+1];
  915. DWORD storedIdSize;
  916. WCHAR indexName[16];
  917. HKEY registryKey;
  918. DWORD i;
  919. DWORD type;
  920. HANDLE handle;
  921. HANDLE mHandle;
  922. status = DevfileOpen( &mHandle, MOUNTMGR_DEVICE_NAME );
  923. if ( status != ERROR_SUCCESS ) {
  924. return FALSE;
  925. }
  926. status = ClusterRegOpenKey( RegistryKey,
  927. L"MountMgr",
  928. KEY_READ | KEY_WRITE,
  929. &registryKey );
  930. if ( status != ERROR_SUCCESS ) {
  931. DevfileClose( mHandle );
  932. return FALSE;
  933. }
  934. status = FindFirstVolumeForSignature( ResourceHandle,
  935. mHandle,
  936. Signature,
  937. volumeName,
  938. MAX_PATH,
  939. &handle,
  940. NULL,
  941. NULL,
  942. NULL );
  943. if ( status != ERROR_SUCCESS ) {
  944. DevfileClose( mHandle );
  945. ClusterRegCloseKey( registryKey );
  946. return TRUE;
  947. }
  948. i = 0;
  949. while ( status == ERROR_SUCCESS ) {
  950. wsprintfW( indexName, L"%0.5u", i++ );
  951. storedIdSize = MAX_PATH;
  952. status = ClusterRegQueryValue( registryKey,
  953. indexName,
  954. &type,
  955. (PUCHAR)storedId,
  956. &storedIdSize);
  957. if ( (status != ERROR_SUCCESS) ||
  958. (type != REG_BINARY) ) {
  959. FindVolumeClose( handle );
  960. DevfileClose( mHandle );
  961. ClusterRegCloseKey( registryKey );
  962. if ( status == ERROR_FILE_NOT_FOUND ) {
  963. return TRUE;
  964. } else {
  965. return FALSE;
  966. }
  967. }
  968. status = FindNextVolumeForSignature( mHandle,
  969. Signature,
  970. handle,
  971. volumeName,
  972. MAX_PATH,
  973. NULL,
  974. NULL,
  975. NULL );
  976. }
  977. FindVolumeClose( handle );
  978. DevfileClose( mHandle );
  979. ClusterRegCloseKey( registryKey );
  980. return TRUE;
  981. } // DisksIsDiskInfoValid
  982. #endif