1 #ifndef _STORDUID_H_ 2 #define _STORDUID_H_ 3 4 typedef enum _DUID_MATCH_STATUS 5 { 6 DuidExactMatch = 0, 7 DuidSubIdMatch, 8 DuidNoMatch, 9 DuidErrorGeneral = 100, 10 DuidErrorMissingDuid, 11 DuidErrorVersionMismatch, 12 DuidErrorInvalidDuid, 13 DuidErrorInvalidDeviceIdDescSize, 14 DuidErrorInvalidDeviceDescSize, 15 DuidErrorInvalidLayoutSigSize, 16 DuidErrorInvalidLayoutSigVersion, 17 DuidErrorMaximum 18 } DUID_MATCH_STATUS; 19 20 #define DUID_VERSION_1 1 21 22 #define DUID_HARDWARE_IDS_ONLY 0 23 #define DUID_INCLUDE_SOFTWARE_IDS 1 24 25 #define DUID_MATCH_ERROR(_duid_status) ((_duid_status) >= DuidErrorGeneral ? TRUE : FALSE) 26 #define DUID_MATCH_SUCCESS(_duid_status) ((_duid_status) < DuidErrorGeneral ? TRUE : FALSE) 27 28 typedef struct _STORAGE_DEVICE_UNIQUE_IDENTIFIER 29 { 30 ULONG Version; 31 ULONG Size; 32 ULONG StorageDeviceIdOffset; 33 ULONG StorageDeviceOffset; 34 ULONG DriveLayoutSignatureOffset; 35 } STORAGE_DEVICE_UNIQUE_IDENTIFIER, *PSTORAGE_DEVICE_UNIQUE_IDENTIFIER; 36 37 typedef struct _STORAGE_DEVICE_LAYOUT_SIGNATURE 38 { 39 ULONG Version; 40 ULONG Size; 41 BOOLEAN Mbr; 42 union { 43 ULONG MbrSignature; 44 GUID GptDiskId; 45 } DeviceSpecific; 46 } STORAGE_DEVICE_LAYOUT_SIGNATURE, *PSTORAGE_DEVICE_LAYOUT_SIGNATURE; 47 48 inline 49 DUID_MATCH_STATUS 50 CompareStorageDuids( 51 _In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid1, 52 _In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid2); 53 54 inline 55 DUID_MATCH_STATUS 56 CompareStorageDuids( 57 _In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid1, 58 _In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid2) 59 { 60 if (!Duid1 || !Duid2) 61 { 62 return DuidErrorMissingDuid; 63 } 64 65 if (Duid1->Size < sizeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER) || 66 Duid2->Size < sizeof(STORAGE_DEVICE_UNIQUE_IDENTIFIER)) 67 { 68 return DuidErrorGeneral; 69 } 70 71 if (Duid1->Version != DUID_VERSION_1 || Duid2->Version != DUID_VERSION_1) 72 { 73 return DuidErrorVersionMismatch; 74 } 75 76 if (Duid1->StorageDeviceIdOffset == 0 && Duid1->StorageDeviceOffset == 0 && 77 Duid1->DriveLayoutSignatureOffset == 0) 78 { 79 return DuidErrorInvalidDuid; 80 } 81 82 if (Duid2->StorageDeviceIdOffset == 0 && Duid2->StorageDeviceOffset == 0 && 83 Duid2->DriveLayoutSignatureOffset == 0) 84 { 85 return DuidErrorInvalidDuid; 86 } 87 88 if (Duid1->Size == Duid2->Size) 89 { 90 if (memcmp(Duid1, Duid2, Duid1->Size) == 0) 91 { 92 return DuidExactMatch; 93 } 94 } 95 96 if (Duid1->StorageDeviceIdOffset && Duid2->StorageDeviceIdOffset) 97 { 98 PSTORAGE_DEVICE_ID_DESCRIPTOR idDesc1; 99 PSTORAGE_DEVICE_ID_DESCRIPTOR idDesc2; 100 101 PSTORAGE_IDENTIFIER ident1; 102 PSTORAGE_IDENTIFIER ident2; 103 104 ULONG idx1; 105 ULONG idx2; 106 107 idDesc1 = (PSTORAGE_DEVICE_ID_DESCRIPTOR)((PUCHAR)Duid1 + Duid1->StorageDeviceIdOffset); 108 idDesc2 = (PSTORAGE_DEVICE_ID_DESCRIPTOR)((PUCHAR)Duid2 + Duid2->StorageDeviceIdOffset); 109 110 if (idDesc1->Size < sizeof(STORAGE_DEVICE_ID_DESCRIPTOR) || 111 idDesc2->Size < sizeof(STORAGE_DEVICE_ID_DESCRIPTOR)) 112 { 113 return DuidErrorInvalidDeviceIdDescSize; 114 } 115 116 if (idDesc1->Size == idDesc2->Size) 117 { 118 if (memcmp(idDesc1, idDesc2, idDesc1->Size) == 0) 119 { 120 return DuidSubIdMatch; 121 } 122 } 123 124 ident1 = (PSTORAGE_IDENTIFIER)(idDesc1->Identifiers); 125 126 for (idx1 = 0; idx1 < idDesc1->NumberOfIdentifiers; idx1++) 127 { 128 if ((ident1->Type == StorageIdTypeScsiNameString || ident1->Type == StorageIdTypeFCPHName || 129 ident1->Type == StorageIdTypeEUI64 || ident1->Type == StorageIdTypeVendorId) && 130 (ident1->Association == StorageIdAssocPort) && 131 (ident1->CodeSet == StorageIdCodeSetUtf8 || ident1->CodeSet == StorageIdCodeSetAscii || 132 ident1->CodeSet == StorageIdCodeSetBinary)) 133 { 134 ident2 = (PSTORAGE_IDENTIFIER)(idDesc2->Identifiers); 135 136 for (idx2 = 0; idx2 < idDesc2->NumberOfIdentifiers; idx2++) 137 { 138 if (ident1->Type == ident2->Type && ident1->Association == ident2->Association && 139 ident1->CodeSet == ident2->CodeSet && 140 ident1->IdentifierSize == ident2->IdentifierSize && 141 (memcmp(ident1->Identifier, ident2->Identifier, ident1->IdentifierSize) == 0)) 142 { 143 return DuidSubIdMatch; 144 } 145 146 ident2 = (PSTORAGE_IDENTIFIER)((PUCHAR)ident2 + ident2->NextOffset); 147 } 148 } 149 150 ident1 = (PSTORAGE_IDENTIFIER)((PUCHAR)ident1 + ident1->NextOffset); 151 } 152 } 153 154 if (Duid1->StorageDeviceOffset && Duid2->StorageDeviceOffset) 155 { 156 PSTORAGE_DEVICE_DESCRIPTOR desc1; 157 PSTORAGE_DEVICE_DESCRIPTOR desc2; 158 159 desc1 = (PSTORAGE_DEVICE_DESCRIPTOR)((PUCHAR)Duid1 + Duid1->StorageDeviceOffset); 160 desc2 = (PSTORAGE_DEVICE_DESCRIPTOR)((PUCHAR)Duid2 + Duid2->StorageDeviceOffset); 161 162 if (desc1->Size < sizeof(STORAGE_DEVICE_DESCRIPTOR) || 163 desc2->Size < sizeof(STORAGE_DEVICE_DESCRIPTOR)) 164 { 165 return DuidErrorInvalidDeviceDescSize; 166 } 167 168 if (desc1->Size == desc2->Size) 169 { 170 if (memcmp(desc1, desc2, desc1->Size) == 0) 171 { 172 return DuidSubIdMatch; 173 } 174 } 175 176 if (desc1->SerialNumberOffset && desc2->SerialNumberOffset) 177 { 178 const char *string1; 179 const char *string2; 180 181 string1 = (const char *)((PUCHAR)desc1 + desc1->SerialNumberOffset); 182 string2 = (const char *)((PUCHAR)desc2 + desc2->SerialNumberOffset); 183 184 if (strcmp(string1, string2) == 0) 185 { 186 if (desc1->VendorIdOffset && desc2->VendorIdOffset) 187 { 188 string1 = (const char *)((PUCHAR)desc1 + desc1->VendorIdOffset); 189 string2 = (const char *)((PUCHAR)desc2 + desc2->VendorIdOffset); 190 191 if (strcmp(string1, string2) != 0) 192 { 193 return DuidNoMatch; 194 } 195 } 196 197 if (desc1->ProductIdOffset && desc2->ProductIdOffset) 198 { 199 string1 = (const char *)((PUCHAR)desc1 + desc1->ProductIdOffset); 200 string2 = (const char *)((PUCHAR)desc2 + desc2->ProductIdOffset); 201 202 if (strcmp(string1, string2) != 0) 203 { 204 return DuidNoMatch; 205 } 206 } 207 208 return DuidSubIdMatch; 209 } 210 } 211 } 212 213 if (Duid1->DriveLayoutSignatureOffset && Duid2->DriveLayoutSignatureOffset) 214 { 215 PSTORAGE_DEVICE_LAYOUT_SIGNATURE sig1; 216 PSTORAGE_DEVICE_LAYOUT_SIGNATURE sig2; 217 218 sig1 = (PSTORAGE_DEVICE_LAYOUT_SIGNATURE)((PUCHAR)Duid1 + Duid1->DriveLayoutSignatureOffset); 219 sig2 = (PSTORAGE_DEVICE_LAYOUT_SIGNATURE)((PUCHAR)Duid2 + Duid2->DriveLayoutSignatureOffset); 220 221 if (sig1->Version != DUID_VERSION_1 && sig2->Version != DUID_VERSION_1) 222 { 223 return DuidErrorInvalidLayoutSigVersion; 224 } 225 226 if (sig1->Size < sizeof(STORAGE_DEVICE_LAYOUT_SIGNATURE) || 227 sig2->Size < sizeof(STORAGE_DEVICE_LAYOUT_SIGNATURE)) 228 { 229 return DuidErrorInvalidLayoutSigSize; 230 } 231 232 if (memcmp(sig1, sig2, sizeof(STORAGE_DEVICE_LAYOUT_SIGNATURE)) == 0) 233 { 234 return DuidSubIdMatch; 235 } 236 } 237 238 return DuidNoMatch; 239 } 240 241 #endif /* _STORDUID_H_ */ 242