xref: /reactos/sdk/include/ddk/storduid.h (revision 15a7b9dd)
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 FORCEINLINE
49 DUID_MATCH_STATUS
50 CompareStorageDuids(
51   _In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid1,
52   _In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid2);
53 
54 FORCEINLINE
55 DUID_MATCH_STATUS
CompareStorageDuids(_In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid1,_In_ PSTORAGE_DEVICE_UNIQUE_IDENTIFIER Duid2)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