312 lines
8.6 KiB
C
312 lines
8.6 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1996 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
partiton.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
Partition scanning routines and assigning Dos Device Letters.
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Rod Gamache (rodga) 20-Feb-1996
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "windows.h"
|
|||
|
#include "winioctl.h"
|
|||
|
#include "ntddscsi.h"
|
|||
|
#include "string.h"
|
|||
|
#include "stdio.h"
|
|||
|
#include "stdlib.h"
|
|||
|
|
|||
|
#include "disksp.h"
|
|||
|
#include "clusdisk.h"
|
|||
|
#include "lm.h"
|
|||
|
#include "lmerr.h"
|
|||
|
|
|||
|
|
|||
|
#define UNICODE 1
|
|||
|
#define ENTRIES_PER_BOOTSECTOR 8
|
|||
|
|
|||
|
|
|||
|
BOOLEAN
|
|||
|
GetAssignedDriveLetter(
|
|||
|
ULONG Signature,
|
|||
|
LARGE_INTEGER StartingOffset,
|
|||
|
LARGE_INTEGER Length,
|
|||
|
PUCHAR DriveLetter,
|
|||
|
PULONG Partition
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
AssignDriveLetters(
|
|||
|
PDISK_INFO DiskInfo
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine scans the partitions on a specified volume and assigns device
|
|||
|
letters. If the DosDeviceLetter has already been assigned, then everything
|
|||
|
is fine. Otherwise, the 'sticky' device letter from the registry is used.
|
|||
|
An error is returned if there is a partition that does not have any
|
|||
|
registry information or no 'sticky' device letter.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DiskInfo - The disk information for this partition.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32 Error Status - ERROR_SUCCESS if success.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD status;
|
|||
|
DWORD returnLength;
|
|||
|
DWORD diskSignature;
|
|||
|
DWORD driveLayoutSize;
|
|||
|
DWORD partNumber;
|
|||
|
DWORD index;
|
|||
|
PDRIVE_LAYOUT_INFORMATION driveLayout;
|
|||
|
PPARTITION_INFORMATION partInfo;
|
|||
|
WCHAR targetPath[100];
|
|||
|
WCHAR newName[8];
|
|||
|
UCHAR driveLetter;
|
|||
|
BOOL success;
|
|||
|
DWORD partition;
|
|||
|
|
|||
|
driveLayoutSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
|
|||
|
(sizeof(PARTITION_INFORMATION) * MAX_PARTITIONS);
|
|||
|
|
|||
|
driveLayout = LocalAlloc( LMEM_FIXED, driveLayoutSize );
|
|||
|
|
|||
|
ZeroMemory( driveLayout, driveLayoutSize );
|
|||
|
|
|||
|
if ( !driveLayout ) {
|
|||
|
printf( "AssignDriveLetters, failed to allocate drive layout info.\n");
|
|||
|
return(ERROR_OUTOFMEMORY);
|
|||
|
}
|
|||
|
|
|||
|
success = DeviceIoControl( DiskInfo->FileHandle,
|
|||
|
IOCTL_DISK_GET_DRIVE_LAYOUT,
|
|||
|
NULL,
|
|||
|
0,
|
|||
|
driveLayout,
|
|||
|
driveLayoutSize,
|
|||
|
&returnLength,
|
|||
|
FALSE );
|
|||
|
|
|||
|
if ( !success ) {
|
|||
|
printf( "AssignDriveLetters, error getting drive layout, %u.\n",
|
|||
|
status = GetLastError() );
|
|||
|
LocalFree( driveLayout );
|
|||
|
return(status);
|
|||
|
}
|
|||
|
|
|||
|
if ( returnLength < (sizeof(DRIVE_LAYOUT_INFORMATION) +
|
|||
|
(sizeof(PARTITION_INFORMATION) *
|
|||
|
(driveLayout->PartitionCount-1))) ) {
|
|||
|
printf("Found %d partitons, need %u, return size %u.\n",
|
|||
|
driveLayout->PartitionCount, sizeof(DRIVE_LAYOUT_INFORMATION) +
|
|||
|
(sizeof(PARTITION_INFORMATION) * (driveLayout->PartitionCount - 1)), returnLength);
|
|||
|
printf("AssignDriveLetters, error getting drive layout. Zero length returned.\n");
|
|||
|
LocalFree( driveLayout );
|
|||
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Process all partitions, assigning drive letters.
|
|||
|
//
|
|||
|
|
|||
|
ZeroMemory(DiskInfo->Letters, sizeof(DiskInfo->Letters));
|
|||
|
|
|||
|
for ( index = 0;
|
|||
|
(index < driveLayout->PartitionCount) &&
|
|||
|
(index < ENTRIES_PER_BOOTSECTOR);
|
|||
|
index++ ) {
|
|||
|
|
|||
|
partInfo = &driveLayout->PartitionEntry[index];
|
|||
|
if ( (partInfo->PartitionType == PARTITION_ENTRY_UNUSED) ||
|
|||
|
!partInfo->RecognizedPartition ) {
|
|||
|
printf("AssignDriveLetters, unused partition found, index %u.\n", index);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
partNumber = partInfo->PartitionNumber;
|
|||
|
|
|||
|
if ( partNumber > MAX_PARTITIONS ) {
|
|||
|
printf("AssignDriveLetters, bad partition number %u, index %u.\n",
|
|||
|
partNumber, index);
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
GetAssignedDriveLetter( driveLayout->Signature,
|
|||
|
partInfo->StartingOffset,
|
|||
|
partInfo->PartitionLength,
|
|||
|
&driveLetter,
|
|||
|
&partition );
|
|||
|
|
|||
|
printf("AssignDriveLetters found letter %c, partition %u, offset %u, length %u.\n",
|
|||
|
driveLetter, partNumber, partInfo->StartingOffset, partInfo->PartitionLength);
|
|||
|
if ( driveLetter != ' ' ) {
|
|||
|
|
|||
|
DiskInfo->Letters[partNumber] = driveLetter;
|
|||
|
swprintf( targetPath,
|
|||
|
L"\\Device\\Harddisk%d\\Partition%d",
|
|||
|
DiskInfo->PhysicalDrive,
|
|||
|
partNumber );
|
|||
|
|
|||
|
newName[0] = (TCHAR)driveLetter;
|
|||
|
newName[1] = (TCHAR)':';
|
|||
|
newName[2] = 0;
|
|||
|
|
|||
|
DefineDosDeviceW( DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM,
|
|||
|
newName,
|
|||
|
targetPath );
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
LocalFree( driveLayout );
|
|||
|
|
|||
|
return(ERROR_SUCCESS);
|
|||
|
|
|||
|
} // AssignDriveLetters
|
|||
|
|
|||
|
|
|||
|
|
|||
|
DWORD
|
|||
|
RemoveDriveLetters(
|
|||
|
PDISK_INFO DiskInfo
|
|||
|
)
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine scans the partitions on a specified volume and removes device
|
|||
|
letters. If the DosDeviceLetter has already been assigned, then everything
|
|||
|
is fine. Otherwise, the 'sticky' device letter from the registry is used.
|
|||
|
An error is returned if there is a partition that does not have any
|
|||
|
registry information or no 'sticky' device letter.
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
DiskInfo - The disk information for this partition.
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
Win32 Error Status - ERROR_SUCCESS if success.
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
DWORD status;
|
|||
|
DWORD returnLength;
|
|||
|
DWORD diskSignature;
|
|||
|
DWORD driveLayoutSize;
|
|||
|
DWORD index;
|
|||
|
PDRIVE_LAYOUT_INFORMATION driveLayout;
|
|||
|
PPARTITION_INFORMATION partInfo;
|
|||
|
TCHAR newName[8];
|
|||
|
WCHAR shareName[8];
|
|||
|
UCHAR driveLetter;
|
|||
|
BOOL success;
|
|||
|
DWORD partition;
|
|||
|
|
|||
|
driveLayoutSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
|
|||
|
(sizeof(PARTITION_INFORMATION) * MAX_PARTITIONS);
|
|||
|
|
|||
|
driveLayout = LocalAlloc( LMEM_FIXED, driveLayoutSize );
|
|||
|
|
|||
|
if ( !driveLayout ) {
|
|||
|
printf("RemoveDriveLetters, failed to allocate drive layout info.\n");
|
|||
|
return(ERROR_OUTOFMEMORY);
|
|||
|
}
|
|||
|
|
|||
|
success = DeviceIoControl( DiskInfo->FileHandle,
|
|||
|
IOCTL_DISK_GET_DRIVE_LAYOUT,
|
|||
|
NULL,
|
|||
|
0,
|
|||
|
driveLayout,
|
|||
|
driveLayoutSize,
|
|||
|
&returnLength,
|
|||
|
FALSE );
|
|||
|
|
|||
|
if ( !success ) {
|
|||
|
printf("RemoveDriveLetters, error getting partition information, %u.\n",
|
|||
|
status = GetLastError() );
|
|||
|
LocalFree( driveLayout );
|
|||
|
return(status);
|
|||
|
}
|
|||
|
|
|||
|
if ( returnLength < (sizeof(DRIVE_LAYOUT_INFORMATION) +
|
|||
|
sizeof(PARTITION_INFORMATION)) ) {
|
|||
|
printf("RemoveDriveLetters, error getting partition information. Zero length returned.\n");
|
|||
|
LocalFree( driveLayout );
|
|||
|
return(ERROR_INSUFFICIENT_BUFFER);
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Process all partitions, assigning drive letters.
|
|||
|
//
|
|||
|
|
|||
|
for ( index = 0;
|
|||
|
(index < driveLayout->PartitionCount) &&
|
|||
|
(index < ENTRIES_PER_BOOTSECTOR);
|
|||
|
index++ ) {
|
|||
|
|
|||
|
partInfo = &driveLayout->PartitionEntry[index];
|
|||
|
|
|||
|
if ( (partInfo->PartitionType == PARTITION_ENTRY_UNUSED) ||
|
|||
|
!partInfo->RecognizedPartition ) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
GetAssignedDriveLetter( driveLayout->Signature,
|
|||
|
partInfo->StartingOffset,
|
|||
|
partInfo->PartitionLength,
|
|||
|
&driveLetter,
|
|||
|
&partition );
|
|||
|
|
|||
|
printf("Found letter %c, offset %u, length %u\n",
|
|||
|
driveLetter, partInfo->StartingOffset, partInfo->PartitionLength);
|
|||
|
if ( driveLetter != ' ' ) {
|
|||
|
|
|||
|
newName[0] = (TCHAR)driveLetter;
|
|||
|
newName[1] = (TCHAR)':';
|
|||
|
newName[2] = (TCHAR)0;
|
|||
|
|
|||
|
shareName[0] = (WCHAR)driveLetter;
|
|||
|
shareName[1] = (WCHAR)'$';
|
|||
|
shareName[2] = (WCHAR)0;
|
|||
|
#if 0
|
|||
|
NetShareDel( NULL,
|
|||
|
shareName,
|
|||
|
0 );
|
|||
|
#endif
|
|||
|
success = DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM,
|
|||
|
newName,
|
|||
|
(LPCTSTR) NULL );
|
|||
|
if ( !success ) {
|
|||
|
printf("RemoveDriveLetters, error removing definition for device %c:.\n",
|
|||
|
driveLetter);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
LocalFree( driveLayout );
|
|||
|
|
|||
|
return(ERROR_SUCCESS);
|
|||
|
|
|||
|
} // RemoveDriveLetters
|
|||
|
|