]> git.proxmox.com Git - mirror_edk2.git/blob - EdkNt32Pkg/Dxe/WinNtThunk/Bus/WinNtBusDriver/WinNtBusDriver.c
Check in the Pcd service Driver/PEIM according to the new way of generating PCD Database
[mirror_edk2.git] / EdkNt32Pkg / Dxe / WinNtThunk / Bus / WinNtBusDriver / WinNtBusDriver.c
1 /*+++
2
3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 WinNtBusDriver.c
15
16 Abstract:
17
18 This following section documents the envirnoment variables for the Win NT
19 build. These variables are used to define the (virtual) hardware
20 configuration of the NT environment
21
22 A ! can be used to seperate multiple instances in a variable. Each
23 instance represents a seperate hardware device.
24
25 EFI_WIN_NT_PHYSICAL_DISKS - maps to drives on your system
26 EFI_WIN_NT_VIRTUAL_DISKS - maps to a device emulated by a file
27 EFI_WIN_NT_FILE_SYSTEM - mouts a directory as a file system
28 EFI_WIN_NT_CONSOLE - make a logical comand line window (only one!)
29 EFI_WIN_NT_UGA - Builds UGA Windows of Width and Height
30 EFI_WIN_NT_SERIAL_PORT - maps physical serial ports
31
32 <F>ixed - Fixed disk like a hard drive.
33 <R>emovable - Removable media like a floppy or CD-ROM.
34 Read <O>nly - Write protected device.
35 Read <W>rite - Read write device.
36 <block count> - Decimal number of blocks a device supports.
37 <block size> - Decimal number of bytes per block.
38
39 NT envirnonment variable contents. '<' and '>' are not part of the variable,
40 they are just used to make this help more readable. There should be no
41 spaces between the ';'. Extra spaces will break the variable. A '!' is
42 used to seperate multiple devices in a variable.
43
44 EFI_WIN_NT_VIRTUAL_DISKS =
45 <F | R><O | W>;<block count>;<block size>[!...]
46
47 EFI_WIN_NT_PHYSICAL_DISKS =
48 <drive letter>:<F | R><O | W>;<block count>;<block size>[!...]
49
50 Virtual Disks: These devices use a file to emulate a hard disk or removable
51 media device.
52
53 Thus a 20 MB emulated hard drive would look like:
54 EFI_WIN_NT_VIRTUAL_DISKS=FW;40960;512
55
56 A 1.44MB emulated floppy with a block size of 1024 would look like:
57 EFI_WIN_NT_VIRTUAL_DISKS=RW;1440;1024
58
59 Physical Disks: These devices use NT to open a real device in your system
60
61 Thus a 120 MB floppy would look like:
62 EFI_WIN_NT_PHYSICAL_DISKS=B:RW;245760;512
63
64 Thus a standard CD-ROM floppy would look like:
65 EFI_WIN_NT_PHYSICAL_DISKS=Z:RO;307200;2048
66
67 EFI_WIN_NT_FILE_SYSTEM =
68 <directory path>[!...]
69
70 Mounting the two directories C:\FOO and C:\BAR would look like:
71 EFI_WIN_NT_FILE_SYSTEM=c:\foo!c:\bar
72
73 EFI_WIN_NT_CONSOLE =
74 <window title>
75
76 Declaring a text console window with the title "My EFI Console" woild look like:
77 EFI_WIN_NT_CONSOLE=My EFI Console
78
79 EFI_WIN_NT_UGA =
80 <width> <height>[!...]
81
82 Declaring a two UGA windows with resolutions of 800x600 and 1024x768 would look like:
83 Example : EFI_WIN_NT_UGA=800 600!1024 768
84
85 EFI_WIN_NT_SERIAL_PORT =
86 <port name>[!...]
87
88 Declaring two serial ports on COM1 and COM2 would look like:
89 Example : EFI_WIN_NT_SERIAL_PORT=COM1!COM2
90
91 EFI_WIN_NT_PASS_THROUGH =
92 <BaseAddress>;<Bus#>;<Device#>;<Function#>
93
94 Declaring a base address of 0xE0000000 (used for PCI Express devices)
95 and having NT32 talk to a device located at bus 0, device 1, function 0:
96 Example : EFI_WIN_NT_PASS_THROUGH=E000000;0;1;0
97
98 ---*/
99
100 #include "WinNtBusDriver.h"
101 //#include "PciHostBridge.h"
102
103 //
104 // Define GUID for the WinNt Bus Driver
105 //
106 static EFI_GUID gWinNtBusDriverGuid = {
107 0x419f582, 0x625, 0x4531, 0x8a, 0x33, 0x85, 0xa9, 0x96, 0x5c, 0x95, 0xbc
108 };
109
110 //
111 // DriverBinding protocol global
112 //
113 EFI_DRIVER_BINDING_PROTOCOL gWinNtBusDriverBinding = {
114 WinNtBusDriverBindingSupported,
115 WinNtBusDriverBindingStart,
116 WinNtBusDriverBindingStop,
117 0x10,
118 NULL,
119 NULL
120 };
121
122 #define NT_PCD_ARRAY_SIZE (sizeof(mPcdEnvironment)/sizeof(NT_PCD_ENTRY))
123
124 //
125 // Table to map NT Environment variable to the GUID that should be in
126 // device path.
127 //
128 static NT_PCD_ENTRY mPcdEnvironment[] = {
129 PcdToken(PcdWinNtConsole), &gEfiWinNtConsoleGuid,
130 PcdToken(PcdWinNtUga), &gEfiWinNtUgaGuid,
131 PcdToken(PcdWinNtSerialPort), &gEfiWinNtSerialPortGuid,
132 PcdToken(PcdWinNtFileSystem), &gEfiWinNtFileSystemGuid,
133 PcdToken(PcdWinNtVirtualDisk), &gEfiWinNtVirtualDisksGuid,
134 PcdToken(PcdWinNtPhysicalDisk), &gEfiWinNtPhysicalDisksGuid,
135 PcdToken(PcdWinNtCpuModel), &gEfiWinNtCPUModelGuid,
136 PcdToken(PcdWinNtCpuSpeed), &gEfiWinNtCPUSpeedGuid,
137 PcdToken(PcdWinNtMemorySize), &gEfiWinNtMemoryGuid
138 };
139
140 VOID *
141 AllocateMemory (
142 IN UINTN Size
143 )
144 {
145 EFI_STATUS Status;
146 VOID *Buffer;
147
148 Status = gBS->AllocatePool (
149 EfiBootServicesData,
150 Size,
151 (VOID *)&Buffer
152 );
153 if (EFI_ERROR (Status)) {
154 ASSERT (FALSE);
155 return NULL;
156 }
157 return Buffer;
158 }
159
160
161 EFI_STATUS
162 EFIAPI
163 WinNtBusDriverBindingSupported (
164 IN EFI_DRIVER_BINDING_PROTOCOL *This,
165 IN EFI_HANDLE ControllerHandle,
166 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
167 )
168 /*++
169
170 Routine Description:
171
172 Arguments:
173
174 Returns:
175
176 None
177
178 --*/
179 // TODO: This - add argument and description to function comment
180 // TODO: ControllerHandle - add argument and description to function comment
181 // TODO: RemainingDevicePath - add argument and description to function comment
182 // TODO: EFI_UNSUPPORTED - add return value to function comment
183 // TODO: EFI_UNSUPPORTED - add return value to function comment
184 // TODO: EFI_SUCCESS - add return value to function comment
185 // TODO: EFI_SUCCESS - add return value to function comment
186 {
187 EFI_STATUS Status;
188 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
189 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;
190 UINTN Index;
191
192 //
193 // Check the contents of the first Device Path Node of RemainingDevicePath to make sure
194 // it is a legal Device Path Node for this bus driver's children.
195 //
196 if (RemainingDevicePath != NULL) {
197 if (RemainingDevicePath->Type != HARDWARE_DEVICE_PATH ||
198 RemainingDevicePath->SubType != HW_VENDOR_DP ||
199 DevicePathNodeLength(RemainingDevicePath) != sizeof(WIN_NT_VENDOR_DEVICE_PATH_NODE)) {
200 return EFI_UNSUPPORTED;
201 }
202
203 for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {
204 if (CompareGuid (&((VENDOR_DEVICE_PATH *) RemainingDevicePath)->Guid, mPcdEnvironment[Index].DevicePathGuid)) {
205 break;
206 }
207 }
208
209 if (Index >= NT_PCD_ARRAY_SIZE) {
210 return EFI_UNSUPPORTED;
211 }
212 }
213
214 //
215 // Open the IO Abstraction(s) needed to perform the supported test
216 //
217 Status = gBS->OpenProtocol (
218 ControllerHandle,
219 &gEfiDevicePathProtocolGuid,
220 &ParentDevicePath,
221 This->DriverBindingHandle,
222 ControllerHandle,
223 EFI_OPEN_PROTOCOL_BY_DRIVER
224 );
225 if (Status == EFI_ALREADY_STARTED) {
226 return EFI_SUCCESS;
227 }
228
229 if (EFI_ERROR (Status)) {
230 return Status;
231 }
232
233 gBS->CloseProtocol (
234 ControllerHandle,
235 &gEfiDevicePathProtocolGuid,
236 This->DriverBindingHandle,
237 ControllerHandle
238 );
239
240 Status = gBS->OpenProtocol (
241 ControllerHandle,
242 &gEfiWinNtThunkProtocolGuid,
243 &WinNtThunk,
244 This->DriverBindingHandle,
245 ControllerHandle,
246 EFI_OPEN_PROTOCOL_BY_DRIVER
247 );
248 if (Status == EFI_ALREADY_STARTED) {
249 return EFI_SUCCESS;
250 }
251
252 if (EFI_ERROR (Status)) {
253 return Status;
254 }
255
256 //
257 // Since we call through WinNtThunk we need to make sure it's valid
258 //
259 Status = EFI_SUCCESS;
260 if (WinNtThunk->Signature != EFI_WIN_NT_THUNK_PROTOCOL_SIGNATURE) {
261 Status = EFI_UNSUPPORTED;
262 }
263
264 //
265 // Close the I/O Abstraction(s) used to perform the supported test
266 //
267 gBS->CloseProtocol (
268 ControllerHandle,
269 &gEfiWinNtThunkProtocolGuid,
270 This->DriverBindingHandle,
271 ControllerHandle
272 );
273
274 return Status;
275 }
276
277 EFI_STATUS
278 EFIAPI
279 WinNtBusDriverBindingStart (
280 IN EFI_DRIVER_BINDING_PROTOCOL *This,
281 IN EFI_HANDLE ControllerHandle,
282 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
283 )
284 /*++
285
286 Routine Description:
287
288 Arguments:
289
290 Returns:
291
292 None
293
294 --*/
295 // TODO: This - add argument and description to function comment
296 // TODO: ControllerHandle - add argument and description to function comment
297 // TODO: RemainingDevicePath - add argument and description to function comment
298 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
299 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
300 // TODO: EFI_SUCCESS - add return value to function comment
301 {
302 EFI_STATUS Status;
303 EFI_STATUS InstallStatus;
304 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;
305 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
306 WIN_NT_BUS_DEVICE *WinNtBusDevice;
307 WIN_NT_IO_DEVICE *WinNtDevice;
308 UINTN Index;
309 CHAR16 *StartString;
310 CHAR16 *SubString;
311 UINT16 Count;
312 UINTN StringSize;
313 UINT16 ComponentName[MAX_NT_ENVIRNMENT_VARIABLE_LENGTH];
314 WIN_NT_VENDOR_DEVICE_PATH_NODE *Node;
315 BOOLEAN CreateDevice;
316 CHAR16 *TempStr;
317 CHAR16 *PcdTempStr;
318 UINTN TempStrSize;
319
320 //
321 // Test Feature Set and Binary Patchable Case
322 //
323 if (FeaturePcdGet (PcdWinNtFeatureFlag1)) {
324 TempStrSize = PatchPcdGet32(PcdWinNtBinaryPatch1) + PatchPcdGet32(PcdWinNtBinaryPatch2);
325 }
326
327 if (0) {
328 //
329 // Test Dynamic and DynamicEx
330 // (Please add PcdWinNtConsole in "WinNtBusDriver.inf" before enable this code!!!)
331 //
332 PcdTempStr = PcdGetPtr (PcdWinNtConsole);
333 }
334
335 //
336 // Test Dynamic Set and Dynamic Set Ex
337 //
338 PcdSet32 (PcdWinNtDynamicUINT32, 2006);
339
340 Status = EFI_UNSUPPORTED;
341
342 //
343 // Grab the protocols we need
344 //
345 Status = gBS->OpenProtocol (
346 ControllerHandle,
347 &gEfiDevicePathProtocolGuid,
348 &ParentDevicePath,
349 This->DriverBindingHandle,
350 ControllerHandle,
351 EFI_OPEN_PROTOCOL_BY_DRIVER
352 );
353 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
354 return Status;
355 }
356
357 Status = gBS->OpenProtocol (
358 ControllerHandle,
359 &gEfiWinNtThunkProtocolGuid,
360 &WinNtThunk,
361 This->DriverBindingHandle,
362 ControllerHandle,
363 EFI_OPEN_PROTOCOL_BY_DRIVER
364 );
365 if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {
366 return Status;
367 }
368
369 if (Status != EFI_ALREADY_STARTED) {
370 Status = gBS->AllocatePool (
371 EfiBootServicesData,
372 sizeof (WIN_NT_BUS_DEVICE),
373 (VOID *) &WinNtBusDevice
374 );
375 if (EFI_ERROR (Status)) {
376 return Status;
377 }
378
379 WinNtBusDevice->Signature = WIN_NT_BUS_DEVICE_SIGNATURE;
380 WinNtBusDevice->ControllerNameTable = NULL;
381
382 AddUnicodeString (
383 "eng",
384 gWinNtBusDriverComponentName.SupportedLanguages,
385 &WinNtBusDevice->ControllerNameTable,
386 L"Windows Bus Controller"
387 );
388
389 Status = gBS->InstallMultipleProtocolInterfaces (
390 &ControllerHandle,
391 &gWinNtBusDriverGuid,
392 WinNtBusDevice,
393 NULL
394 );
395 if (EFI_ERROR (Status)) {
396 FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);
397 gBS->FreePool (WinNtBusDevice);
398 return Status;
399 }
400 }
401
402 //
403 // Loop on the Variable list. Parse each variable to produce a set of handles that
404 // represent virtual hardware devices.
405 //
406 InstallStatus = EFI_NOT_FOUND;
407 for (Index = 0; Index < NT_PCD_ARRAY_SIZE; Index++) {
408 PcdTempStr = (VOID *)LibPcdGetPtr (mPcdEnvironment[Index].Token);
409 ASSERT (PcdTempStr != NULL);
410
411 TempStrSize = StrLen (PcdTempStr);
412 TempStr = AllocateMemory ((TempStrSize * sizeof (CHAR16)) + 1);
413 StrCpy (TempStr, PcdTempStr);
414
415 StartString = TempStr;
416
417 //
418 // Parse the envirnment variable into sub strings using '!' as a delimator.
419 // Each substring needs it's own handle to be added to the system. This code
420 // does not understand the sub string. Thats the device drivers job.
421 //
422 Count = 0;
423 while (*StartString != '\0') {
424
425 //
426 // Find the end of the sub string
427 //
428 SubString = StartString;
429 while (*SubString != '\0' && *SubString != '!') {
430 SubString++;
431 }
432
433 if (*SubString == '!') {
434 //
435 // Replace token with '\0' to make sub strings. If this is the end
436 // of the string SubString will already point to NULL.
437 //
438 *SubString = '\0';
439 SubString++;
440 }
441
442 CreateDevice = TRUE;
443 if (RemainingDevicePath != NULL) {
444 CreateDevice = FALSE;
445 Node = (WIN_NT_VENDOR_DEVICE_PATH_NODE *) RemainingDevicePath;
446 if (Node->VendorDevicePath.Header.Type == HARDWARE_DEVICE_PATH &&
447 Node->VendorDevicePath.Header.SubType == HW_VENDOR_DP &&
448 DevicePathNodeLength (&Node->VendorDevicePath.Header) == sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE)
449 ) {
450 if (CompareGuid (&Node->VendorDevicePath.Guid, mPcdEnvironment[Index].DevicePathGuid) &&
451 Node->Instance == Count
452 ) {
453 CreateDevice = TRUE;
454 }
455 }
456 }
457
458 if (CreateDevice) {
459
460 //
461 // Allocate instance structure, and fill in parent information.
462 //
463 WinNtDevice = AllocateMemory (sizeof (WIN_NT_IO_DEVICE));
464 if (WinNtDevice == NULL) {
465 return EFI_OUT_OF_RESOURCES;
466 }
467
468 WinNtDevice->Handle = NULL;
469 WinNtDevice->ControllerHandle = ControllerHandle;
470 WinNtDevice->ParentDevicePath = ParentDevicePath;
471
472 WinNtDevice->WinNtIo.WinNtThunk = WinNtThunk;
473
474 //
475 // Plus 2 to account for the NULL at the end of the Unicode string
476 //
477 StringSize = (UINTN) ((UINT8 *) SubString - (UINT8 *) StartString) + sizeof (CHAR16);
478 WinNtDevice->WinNtIo.EnvString = AllocateMemory (StringSize);
479 if (WinNtDevice->WinNtIo.EnvString != NULL) {
480 CopyMem (WinNtDevice->WinNtIo.EnvString, StartString, StringSize);
481 }
482
483 WinNtDevice->ControllerNameTable = NULL;
484
485 WinNtThunk->SPrintf (ComponentName, L"%s", WinNtDevice->WinNtIo.EnvString);
486
487 WinNtDevice->DevicePath = WinNtBusCreateDevicePath (
488 ParentDevicePath,
489 mPcdEnvironment[Index].DevicePathGuid,
490 Count
491 );
492 if (WinNtDevice->DevicePath == NULL) {
493 gBS->FreePool (WinNtDevice);
494 return EFI_OUT_OF_RESOURCES;
495 }
496
497 AddUnicodeString (
498 "eng",
499 gWinNtBusDriverComponentName.SupportedLanguages,
500 &WinNtDevice->ControllerNameTable,
501 ComponentName
502 );
503
504 WinNtDevice->WinNtIo.TypeGuid = mPcdEnvironment[Index].DevicePathGuid;
505 WinNtDevice->WinNtIo.InstanceNumber = Count;
506
507 WinNtDevice->Signature = WIN_NT_IO_DEVICE_SIGNATURE;
508
509 Status = gBS->InstallMultipleProtocolInterfaces (
510 &WinNtDevice->Handle,
511 &gEfiDevicePathProtocolGuid,
512 WinNtDevice->DevicePath,
513 &gEfiWinNtIoProtocolGuid,
514 &WinNtDevice->WinNtIo,
515 NULL
516 );
517 if (EFI_ERROR (Status)) {
518 FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);
519 gBS->FreePool (WinNtDevice);
520 } else {
521 //
522 // Open For Child Device
523 //
524 Status = gBS->OpenProtocol (
525 ControllerHandle,
526 &gEfiWinNtThunkProtocolGuid,
527 &WinNtThunk,
528 This->DriverBindingHandle,
529 WinNtDevice->Handle,
530 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
531 );
532 if (!EFI_ERROR (Status)) {
533 InstallStatus = EFI_SUCCESS;
534 }
535 }
536 }
537
538 //
539 // Parse Next sub string. This will point to '\0' if we are at the end.
540 //
541 Count++;
542 StartString = SubString;
543 }
544
545 gBS->FreePool (TempStr);
546 }
547
548 return EFI_SUCCESS;
549 }
550
551
552 EFI_STATUS
553 EFIAPI
554 WinNtBusDriverBindingStop (
555 IN EFI_DRIVER_BINDING_PROTOCOL *This,
556 IN EFI_HANDLE ControllerHandle,
557 IN UINTN NumberOfChildren,
558 IN EFI_HANDLE *ChildHandleBuffer
559 )
560 /*++
561
562 Routine Description:
563
564 Arguments:
565
566 Returns:
567
568 None
569
570 --*/
571 // TODO: This - add argument and description to function comment
572 // TODO: ControllerHandle - add argument and description to function comment
573 // TODO: NumberOfChildren - add argument and description to function comment
574 // TODO: ChildHandleBuffer - add argument and description to function comment
575 // TODO: EFI_SUCCESS - add return value to function comment
576 // TODO: EFI_DEVICE_ERROR - add return value to function comment
577 // TODO: EFI_SUCCESS - add return value to function comment
578 {
579 EFI_STATUS Status;
580 UINTN Index;
581 BOOLEAN AllChildrenStopped;
582 EFI_WIN_NT_IO_PROTOCOL *WinNtIo;
583 WIN_NT_BUS_DEVICE *WinNtBusDevice;
584 WIN_NT_IO_DEVICE *WinNtDevice;
585 EFI_WIN_NT_THUNK_PROTOCOL *WinNtThunk;
586
587 //
588 // Complete all outstanding transactions to Controller.
589 // Don't allow any new transaction to Controller to be started.
590 //
591
592 if (NumberOfChildren == 0) {
593 //
594 // Close the bus driver
595 //
596 Status = gBS->OpenProtocol (
597 ControllerHandle,
598 &gWinNtBusDriverGuid,
599 &WinNtBusDevice,
600 This->DriverBindingHandle,
601 ControllerHandle,
602 EFI_OPEN_PROTOCOL_GET_PROTOCOL
603 );
604 if (EFI_ERROR (Status)) {
605 return Status;
606 }
607
608 gBS->UninstallMultipleProtocolInterfaces (
609 ControllerHandle,
610 &gWinNtBusDriverGuid,
611 WinNtBusDevice,
612 NULL
613 );
614
615 FreeUnicodeStringTable (WinNtBusDevice->ControllerNameTable);
616
617 gBS->FreePool (WinNtBusDevice);
618
619 gBS->CloseProtocol (
620 ControllerHandle,
621 &gEfiWinNtThunkProtocolGuid,
622 This->DriverBindingHandle,
623 ControllerHandle
624 );
625
626 gBS->CloseProtocol (
627 ControllerHandle,
628 &gEfiDevicePathProtocolGuid,
629 This->DriverBindingHandle,
630 ControllerHandle
631 );
632 return EFI_SUCCESS;
633 }
634
635 AllChildrenStopped = TRUE;
636
637 for (Index = 0; Index < NumberOfChildren; Index++) {
638
639 Status = gBS->OpenProtocol (
640 ChildHandleBuffer[Index],
641 &gEfiWinNtIoProtocolGuid,
642 &WinNtIo,
643 This->DriverBindingHandle,
644 ControllerHandle,
645 EFI_OPEN_PROTOCOL_GET_PROTOCOL
646 );
647 if (!EFI_ERROR (Status)) {
648
649 WinNtDevice = WIN_NT_IO_DEVICE_FROM_THIS (WinNtIo);
650
651 Status = gBS->CloseProtocol (
652 ControllerHandle,
653 &gEfiWinNtThunkProtocolGuid,
654 This->DriverBindingHandle,
655 WinNtDevice->Handle
656 );
657
658 Status = gBS->UninstallMultipleProtocolInterfaces (
659 WinNtDevice->Handle,
660 &gEfiDevicePathProtocolGuid,
661 WinNtDevice->DevicePath,
662 &gEfiWinNtIoProtocolGuid,
663 &WinNtDevice->WinNtIo,
664 NULL
665 );
666
667 if (EFI_ERROR (Status)) {
668 gBS->OpenProtocol (
669 ControllerHandle,
670 &gEfiWinNtThunkProtocolGuid,
671 (VOID **) &WinNtThunk,
672 This->DriverBindingHandle,
673 WinNtDevice->Handle,
674 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
675 );
676 } else {
677 //
678 // Close the child handle
679 //
680 FreeUnicodeStringTable (WinNtDevice->ControllerNameTable);
681 gBS->FreePool (WinNtDevice);
682 }
683 }
684
685 if (EFI_ERROR (Status)) {
686 AllChildrenStopped = FALSE;
687 }
688 }
689
690 if (!AllChildrenStopped) {
691 return EFI_DEVICE_ERROR;
692 }
693
694 return EFI_SUCCESS;
695 }
696
697 EFI_DEVICE_PATH_PROTOCOL *
698 WinNtBusCreateDevicePath (
699 IN EFI_DEVICE_PATH_PROTOCOL *RootDevicePath,
700 IN EFI_GUID *Guid,
701 IN UINT16 InstanceNumber
702 )
703 /*++
704
705 Routine Description:
706 Create a device path node using Guid and InstanceNumber and append it to
707 the passed in RootDevicePath
708
709 Arguments:
710 RootDevicePath - Root of the device path to return.
711
712 Guid - GUID to use in vendor device path node.
713
714 InstanceNumber - Instance number to use in the vendor device path. This
715 argument is needed to make sure each device path is unique.
716
717 Returns:
718
719 EFI_DEVICE_PATH_PROTOCOL
720
721 --*/
722 {
723 WIN_NT_VENDOR_DEVICE_PATH_NODE DevicePath;
724
725 DevicePath.VendorDevicePath.Header.Type = HARDWARE_DEVICE_PATH;
726 DevicePath.VendorDevicePath.Header.SubType = HW_VENDOR_DP;
727 SetDevicePathNodeLength (&DevicePath.VendorDevicePath.Header, sizeof (WIN_NT_VENDOR_DEVICE_PATH_NODE));
728
729 //
730 // The GUID defines the Class
731 //
732 CopyMem (&DevicePath.VendorDevicePath.Guid, Guid, sizeof (EFI_GUID));
733
734 //
735 // Add an instance number so we can make sure there are no Device Path
736 // duplication.
737 //
738 DevicePath.Instance = InstanceNumber;
739
740 return AppendDevicePathNode (
741 RootDevicePath,
742 (EFI_DEVICE_PATH_PROTOCOL *) &DevicePath
743 );
744 }