windows-nt/Source/XPSP1/NT/base/cluster/clusdisk/test/partiton.c
2020-09-26 16:20:57 +08:00

312 lines
8.6 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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