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