reactos/sdk/include/ddk/storduid.h
2020-12-05 22:15:29 +03:00

242 lines
6.7 KiB
C

#ifndef _STORDUID_H_
#define _STORDUID_H_
typedef enum _DUID_MATCH_STATUS
{
DuidExactMatch = 0,
DuidSubIdMatch,
DuidNoMatch,
DuidErrorGeneral = 100,
DuidErrorMissingDuid,
DuidErrorVersionMismatch,
DuidErrorInvalidDuid,
DuidErrorInvalidDeviceIdDescSize,
DuidErrorInvalidDeviceDescSize,
DuidErrorInvalidLayoutSigSize,
DuidErrorInvalidLayoutSigVersion,
DuidErrorMaximum
} DUID_MATCH_STATUS;
#define DUID_VERSION_1 1
#define DUID_HARDWARE_IDS_ONLY 0
#define DUID_INCLUDE_SOFTWARE_IDS 1
#define DUID_MATCH_ERROR(_duid_status) ((_duid_status) >= DuidErrorGeneral ? TRUE : FALSE)
#define DUID_MATCH_SUCCESS(_duid_status) ((_duid_status) < DuidErrorGeneral ? TRUE : FALSE)
typedef struct _STORAGE_DEVICE_UNIQUE_IDENTIFIER
{
ULONG Version;
ULONG Size;
ULONG StorageDeviceIdOffset;
ULONG StorageDeviceOffset;
ULONG DriveLayoutSignatureOffset;
} STORAGE_DEVICE_UNIQUE_IDENTIFIER, *PSTORAGE_DEVICE_UNIQUE_IDENTIFIER;
typedef struct _STORAGE_DEVICE_LAYOUT_SIGNATURE
{
ULONG Version;
ULONG Size;
BOOLEAN Mbr;
union {
ULONG MbrSignature;
GUID GptDiskId;
} DeviceSpecific;
} STORAGE_DEVICE_LAYOUT_SIGNATURE, *PSTORAGE_DEVICE_LAYOUT_SIGNATURE;
FORCEINLINE
DUID_MATCH_STATUS
CompareStorageDuids(
_In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid1,
_In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid2);
FORCEINLINE
DUID_MATCH_STATUS
CompareStorageDuids(
_In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid1,
_In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid2)
{
if (!Duid1 || !Duid2)
{
return DuidErrorMissingDuid;
}
if (Duid1->Size < sizeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER) ||
Duid2->Size < sizeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER))
{
return DuidErrorGeneral;
}
if (Duid1->Version != DUID_VERSION_1 || Duid2->Version != DUID_VERSION_1)
{
return DuidErrorVersionMismatch;
}
if (Duid1->StorageDeviceIdOffset == 0 && Duid1->StorageDeviceOffset == 0 &&
Duid1->DriveLayoutSignatureOffset == 0)
{
return DuidErrorInvalidDuid;
}
if (Duid2->StorageDeviceIdOffset == 0 && Duid2->StorageDeviceOffset == 0 &&
Duid2->DriveLayoutSignatureOffset == 0)
{
return DuidErrorInvalidDuid;
}
if (Duid1->Size == Duid2->Size)
{
if (memcmp(Duid1, Duid2, Duid1->Size) == 0)
{
return DuidExactMatch;
}
}
if (Duid1->StorageDeviceIdOffset && Duid2->StorageDeviceIdOffset)
{
PSTORAGE_DEVICE_ID_DESCRIPTOR idDesc1;
PSTORAGE_DEVICE_ID_DESCRIPTOR idDesc2;
PSTORAGE_IDENTIFIER ident1;
PSTORAGE_IDENTIFIER ident2;
ULONG idx1;
ULONG idx2;
idDesc1 = (PSTORAGE_DEVICE_ID_DESCRIPTOR)((PUCHAR)Duid1 + Duid1->StorageDeviceIdOffset);
idDesc2 = (PSTORAGE_DEVICE_ID_DESCRIPTOR)((PUCHAR)Duid2 + Duid2->StorageDeviceIdOffset);
if (idDesc1->Size < sizeof(STORAGE_DEVICE_ID_DESCRIPTOR) ||
idDesc2->Size < sizeof(STORAGE_DEVICE_ID_DESCRIPTOR))
{
return DuidErrorInvalidDeviceIdDescSize;
}
if (idDesc1->Size == idDesc2->Size)
{
if (memcmp(idDesc1, idDesc2, idDesc1->Size) == 0)
{
return DuidSubIdMatch;
}
}
ident1 = (PSTORAGE_IDENTIFIER)(idDesc1->Identifiers);
for (idx1 = 0; idx1 < idDesc1->NumberOfIdentifiers; idx1++)
{
if ((ident1->Type == StorageIdTypeScsiNameString || ident1->Type == StorageIdTypeFCPHName ||
ident1->Type == StorageIdTypeEUI64 || ident1->Type == StorageIdTypeVendorId) &&
(ident1->Association == StorageIdAssocPort) &&
(ident1->CodeSet == StorageIdCodeSetUtf8 || ident1->CodeSet == StorageIdCodeSetAscii ||
ident1->CodeSet == StorageIdCodeSetBinary))
{
ident2 = (PSTORAGE_IDENTIFIER)(idDesc2->Identifiers);
for (idx2 = 0; idx2 < idDesc2->NumberOfIdentifiers; idx2++)
{
if (ident1->Type == ident2->Type && ident1->Association == ident2->Association &&
ident1->CodeSet == ident2->CodeSet &&
ident1->IdentifierSize == ident2->IdentifierSize &&
(memcmp(ident1->Identifier, ident2->Identifier, ident1->IdentifierSize) == 0))
{
return DuidSubIdMatch;
}
ident2 = (PSTORAGE_IDENTIFIER)((PUCHAR)ident2 + ident2->NextOffset);
}
}
ident1 = (PSTORAGE_IDENTIFIER)((PUCHAR)ident1 + ident1->NextOffset);
}
}
if (Duid1->StorageDeviceOffset && Duid2->StorageDeviceOffset)
{
PSTORAGE_DEVICE_DESCRIPTOR desc1;
PSTORAGE_DEVICE_DESCRIPTOR desc2;
desc1 = (PSTORAGE_DEVICE_DESCRIPTOR)((PUCHAR)Duid1 + Duid1->StorageDeviceOffset);
desc2 = (PSTORAGE_DEVICE_DESCRIPTOR)((PUCHAR)Duid2 + Duid2->StorageDeviceOffset);
if (desc1->Size < sizeof(STORAGE_DEVICE_DESCRIPTOR) ||
desc2->Size < sizeof(STORAGE_DEVICE_DESCRIPTOR))
{
return DuidErrorInvalidDeviceDescSize;
}
if (desc1->Size == desc2->Size)
{
if (memcmp(desc1, desc2, desc1->Size) == 0)
{
return DuidSubIdMatch;
}
}
if (desc1->SerialNumberOffset && desc2->SerialNumberOffset)
{
const char *string1;
const char *string2;
string1 = (const char *)((PUCHAR)desc1 + desc1->SerialNumberOffset);
string2 = (const char *)((PUCHAR)desc2 + desc2->SerialNumberOffset);
if (strcmp(string1, string2) == 0)
{
if (desc1->VendorIdOffset && desc2->VendorIdOffset)
{
string1 = (const char *)((PUCHAR)desc1 + desc1->VendorIdOffset);
string2 = (const char *)((PUCHAR)desc2 + desc2->VendorIdOffset);
if (strcmp(string1, string2) != 0)
{
return DuidNoMatch;
}
}
if (desc1->ProductIdOffset && desc2->ProductIdOffset)
{
string1 = (const char *)((PUCHAR)desc1 + desc1->ProductIdOffset);
string2 = (const char *)((PUCHAR)desc2 + desc2->ProductIdOffset);
if (strcmp(string1, string2) != 0)
{
return DuidNoMatch;
}
}
return DuidSubIdMatch;
}
}
}
if (Duid1->DriveLayoutSignatureOffset && Duid2->DriveLayoutSignatureOffset)
{
PSTORAGE_DEVICE_LAYOUT_SIGNATURE sig1;
PSTORAGE_DEVICE_LAYOUT_SIGNATURE sig2;
sig1 = (PSTORAGE_DEVICE_LAYOUT_SIGNATURE)((PUCHAR)Duid1 + Duid1->DriveLayoutSignatureOffset);
sig2 = (PSTORAGE_DEVICE_LAYOUT_SIGNATURE)((PUCHAR)Duid2 + Duid2->DriveLayoutSignatureOffset);
if (sig1->Version != DUID_VERSION_1 && sig2->Version != DUID_VERSION_1)
{
return DuidErrorInvalidLayoutSigVersion;
}
if (sig1->Size < sizeof(STORAGE_DEVICE_LAYOUT_SIGNATURE) ||
sig2->Size < sizeof(STORAGE_DEVICE_LAYOUT_SIGNATURE))
{
return DuidErrorInvalidLayoutSigSize;
}
if (memcmp(sig1, sig2, sizeof(STORAGE_DEVICE_LAYOUT_SIGNATURE)) == 0)
{
return DuidSubIdMatch;
}
}
return DuidNoMatch;
}
#endif /* _STORDUID_H_ */