#include "stdafx.hxx" #include "vss.h" #include "vswriter.h" #include "vsbackup.h" #include #include #include #include #include #include #include #include #include void PrintVolumeInfo(LPWSTR wszVolume) { wprintf(L"\n\nInformation for volume %s\n\n", wszVolume); // get rid of last backslash wszVolume[wcslen(wszVolume)-1] = L'\0'; HANDLE hVol = CreateFile ( wszVolume, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if (hVol == INVALID_HANDLE_VALUE) { DWORD dwErr = GetLastError(); wprintf(L"CreateFile of volume failed with error %d.\n", dwErr); return; } WCHAR bufExtents[1024]; DWORD size; BOOL b = DeviceIoControl ( hVol, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, (PVOID) bufExtents, sizeof(bufExtents), &size, NULL ); if (!b) { DWORD dwErr = GetLastError(); wprintf(L"IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS failed with error %d.\n", dwErr); CloseHandle(hVol); return; } VOLUME_DISK_EXTENTS *pDiskExtents = (VOLUME_DISK_EXTENTS *) bufExtents; ULONG PrevDiskNo = 0xffffffff; printf("# of extents = %d\n\n", pDiskExtents->NumberOfDiskExtents); for(UINT iExtent = 0; iExtent < pDiskExtents->NumberOfDiskExtents; iExtent++) { ULONG DiskNo = pDiskExtents->Extents[iExtent].DiskNumber; printf("Extent %d:\nDisk %d, Low=0x%I64lx, Length=0x%I64lx\n\n", iExtent, DiskNo, pDiskExtents->Extents[iExtent].StartingOffset, pDiskExtents->Extents[iExtent].ExtentLength ); if (DiskNo != PrevDiskNo) { PrevDiskNo = DiskNo; WCHAR wszbuf[32]; swprintf(wszbuf, L"\\\\.\\PHYSICALDRIVE%u", DiskNo); HANDLE hDisk = CreateFile ( wszbuf, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if (hDisk == INVALID_HANDLE_VALUE) { DWORD dwErr = GetLastError(); wprintf(L"Cannot open disk %d due to error %d. Skipping\n", DiskNo, dwErr); continue; } STORAGE_PROPERTY_QUERY query; query.PropertyId = StorageDeviceProperty; query.QueryType = PropertyStandardQuery; BYTE buf[1024]; DWORD dwSize; if (!DeviceIoControl ( hDisk, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), buf, 1024, &dwSize, NULL )) { DWORD dwErr = GetLastError(); if (dwErr != ERROR_NOT_SUPPORTED) wprintf(L"IOCTL_STORAGE_QUERY_PROPERTY failed due to error %d.\n", dwErr); CloseHandle(hDisk); continue; } STORAGE_DEVICE_DESCRIPTOR *pDesc = (STORAGE_DEVICE_DESCRIPTOR *) buf; printf("Information for disk %d.\n\nbus=", DiskNo); switch (pDesc->BusType) { default: printf("(other)\n"); break; case BusTypeScsi: printf("(SCSI)\n"); break; case BusTypeAtapi: printf("(ATAPI)\n"); break; case BusTypeAta: printf("(ATA)\n"); break; case BusType1394: printf("(1394)\n"); break; case BusTypeSsa: printf("(SSA)\n"); break; case BusTypeFibre: printf("(Fibre)\n"); break; case BusTypeUsb: printf("(Usb)\n"); break; case BusTypeRAID: printf("(RAID)\n"); break; } if (pDesc->VendorIdOffset) { LPSTR szVendor = (LPSTR)((BYTE *) pDesc + pDesc->VendorIdOffset); printf("VendorId: %s\n", szVendor); } if (pDesc->ProductIdOffset) { LPSTR szProduct = (LPSTR)((BYTE *) pDesc + pDesc->ProductIdOffset); printf("ProductId: %s\n", szProduct); } if (pDesc->ProductRevisionOffset) { LPSTR szRevision = (LPSTR)((BYTE *) pDesc + pDesc->ProductRevisionOffset); printf("RevisionId: %s\n", szRevision); } if (pDesc->SerialNumberOffset) { LPSTR szSerialNo = (LPSTR)((BYTE *) pDesc + pDesc->SerialNumberOffset); printf("Serial#: %s\n", szSerialNo); } query.PropertyId = StorageDeviceIdProperty; query.QueryType = PropertyStandardQuery; if (!DeviceIoControl ( hDisk, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(query), buf, 1024, &dwSize, NULL )) { DWORD dwErr = GetLastError(); if (dwErr != ERROR_NOT_SUPPORTED) wprintf(L"IOCTL_STORAGE_QUERY_PROPERTY failed due to error %d.\n", dwErr); CloseHandle(hDisk); continue; } STORAGE_DEVICE_ID_DESCRIPTOR *pDevId = (STORAGE_DEVICE_ID_DESCRIPTOR *) buf; printf("# of identifiers = %d\n", pDevId->NumberOfIdentifiers); STORAGE_IDENTIFIER *pId = (STORAGE_IDENTIFIER *) pDevId->Identifiers; for(UINT i = 0; i < pDevId->NumberOfIdentifiers; i++) { switch(pId->Type) { default: printf("(other) "); break; case StorageIdTypeVendorSpecific: printf("(vendor specific) "); break; case StorageIdTypeVendorId: printf("(vendor id) "); break; case StorageIdTypeEUI64: printf("(EUI64) "); break; case StorageIdTypeFCPHName: printf("(FCPHName) "); break; } if (pId->CodeSet == StorageIdCodeSetAscii) printf("%s\n", pId->Identifier); else { for(UINT i = 0; i < pId->IdentifierSize; i++) { printf("%2x ", pId->Identifier[i]); if ((i % 16) == 0 && i > 0) printf("\n"); } } pId = (STORAGE_IDENTIFIER *) ((BYTE *) pId + pId->NextOffset); } CloseHandle(hDisk); } } } void EnumVolumes() { CVssFunctionTracer ft(VSSDBG_XML, L"EnumVolumes"); HANDLE h = INVALID_HANDLE_VALUE; try { WCHAR volName[1024]; h = FindFirstVolume(volName, sizeof(volName)/sizeof(WCHAR)); if (h == INVALID_HANDLE_VALUE) { DWORD dwErr = GetLastError(); Error(E_UNEXPECTED, L"FindFirstVolume failed due to error %d.\n", dwErr); } while(TRUE) { PrintVolumeInfo(volName); if (!FindNextVolume(h, volName, sizeof(volName)/ sizeof(WCHAR))) { DWORD dwErr = GetLastError(); if (dwErr == ERROR_NO_MORE_FILES) break; else Error(E_UNEXPECTED, L"Unexpected error %d from FindNextVolume.\n", dwErr); } } if (!FindVolumeClose(h)) { DWORD dwErr = GetLastError(); Error(E_UNEXPECTED, L"Cannot close volume handle due to error %d.\n", dwErr); } h = INVALID_HANDLE_VALUE; } VSS_STANDARD_CATCH(ft) if (h != INVALID_HANDLE_VALUE) FindClose(h); }