summaryrefslogtreecommitdiff
path: root/general/toaster
diff options
context:
space:
mode:
authorDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
committerDave Wilson <[email protected]>2015-03-17 19:50:07 -0700
commit97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch)
tree46f3701832d70b420eb0fc0eb93261f9da45db3f /general/toaster
parentef1905bf1e8825bb31120dfb27e0daf3154d859a (diff)
Initial publish
Diffstat (limited to 'general/toaster')
-rw-r--r--general/toaster/toastpkg/ReadMe.md21
-rw-r--r--general/toaster/toastpkg/inf/autorun.inf15
-rw-r--r--general/toaster/toastpkg/inf/toastpkg.inf137
-rw-r--r--general/toaster/toastpkg/toastapp/precomp.h21
-rw-r--r--general/toaster/toastpkg/toastapp/precompsrc.c1
-rw-r--r--general/toaster/toastpkg/toastapp/rc_ids.h22
-rw-r--r--general/toaster/toastpkg/toastapp/toastapp.c813
-rw-r--r--general/toaster/toastpkg/toastapp/toastapp.dlg12
-rw-r--r--general/toaster/toastpkg/toastapp/toastapp.h29
-rw-r--r--general/toaster/toastpkg/toastapp/toastapp.icobin0 -> 766 bytes
-rw-r--r--general/toaster/toastpkg/toastapp/toastapp.rc69
-rw-r--r--general/toaster/toastpkg/toastapp/toastapp.vcxproj209
-rw-r--r--general/toaster/toastpkg/toastapp/toastapp.vcxproj.Filters30
-rw-r--r--general/toaster/toastpkg/toastcd/ToastApp/setup.inibin0 -> 758 bytes
-rw-r--r--general/toaster/toastpkg/toastcd/ToastApp/toastapp.msibin0 -> 181760 bytes
-rw-r--r--general/toaster/toastpkg/toastcd/amd64/toaster.sysbin0 -> 41472 bytes
-rw-r--r--general/toaster/toastpkg/toastcd/autorun.inf15
-rw-r--r--general/toaster/toastpkg/toastcd/i386/toaster.sysbin0 -> 24064 bytes
-rw-r--r--general/toaster/toastpkg/toastcd/toastpkg.inf137
-rw-r--r--general/toaster/toastpkg/toastcd/toastpkg.tag0
-rw-r--r--general/toaster/toastpkg/toastcd/tostx86.catbin0 -> 10350 bytes
-rw-r--r--general/toaster/toastpkg/toastcd/tstamd64.catbin0 -> 10252 bytes
-rw-r--r--general/toaster/toastpkg/toastco/precomp.h21
-rw-r--r--general/toaster/toastpkg/toastco/precompsrc.c1
-rw-r--r--general/toaster/toastpkg/toastco/toastco.c1312
-rw-r--r--general/toaster/toastpkg/toastco/toastco.h33
-rw-r--r--general/toaster/toastpkg/toastco/toastco.rc85
-rw-r--r--general/toaster/toastpkg/toastco/tostrco2.def24
-rw-r--r--general/toaster/toastpkg/toastco/tostrco2.vcxproj243
-rw-r--r--general/toaster/toastpkg/toastco/tostrco2.vcxproj.Filters33
-rw-r--r--general/toaster/toastpkg/toastpkg.sln62
-rw-r--r--general/toaster/toastpkg/toastva/header.bmpbin0 -> 5686 bytes
-rw-r--r--general/toaster/toastpkg/toastva/precomp.h21
-rw-r--r--general/toaster/toastpkg/toastva/precompsrc.c1
-rw-r--r--general/toaster/toastpkg/toastva/resource.h61
-rw-r--r--general/toaster/toastpkg/toastva/search.avibin0 -> 20796 bytes
-rw-r--r--general/toaster/toastpkg/toastva/toastapp.icobin0 -> 766 bytes
-rw-r--r--general/toaster/toastpkg/toastva/toastva.c209
-rw-r--r--general/toaster/toastpkg/toastva/toastva.h79
-rw-r--r--general/toaster/toastpkg/toastva/toastva.rc221
-rw-r--r--general/toaster/toastpkg/toastva/toastva.vcxproj221
-rw-r--r--general/toaster/toastpkg/toastva/toastva.vcxproj.Filters36
-rw-r--r--general/toaster/toastpkg/toastva/util.c517
-rw-r--r--general/toaster/toastpkg/toastva/watermrk.bmpbin0 -> 52574 bytes
-rw-r--r--general/toaster/toastpkg/toastva/wizard.c883
-rw-r--r--general/toaster/umdf2/Package/package.VcxProj91
-rw-r--r--general/toaster/umdf2/Package/package.VcxProj.Filters21
-rw-r--r--general/toaster/umdf2/ReadMe.md58
-rw-r--r--general/toaster/umdf2/exe/enum/Enum.vcxproj171
-rw-r--r--general/toaster/umdf2/exe/enum/Enum.vcxproj.Filters22
-rw-r--r--general/toaster/umdf2/exe/enum/enum.c317
-rw-r--r--general/toaster/umdf2/exe/notify/notify.c1244
-rw-r--r--general/toaster/umdf2/exe/notify/notify.h182
-rw-r--r--general/toaster/umdf2/exe/notify/notify.rc77
-rw-r--r--general/toaster/umdf2/exe/notify/notify.vcxproj172
-rw-r--r--general/toaster/umdf2/exe/notify/notify.vcxproj.Filters27
-rw-r--r--general/toaster/umdf2/exe/notify/toaster.icobin0 -> 4534 bytes
-rw-r--r--general/toaster/umdf2/exe/toast/toast.c343
-rw-r--r--general/toaster/umdf2/exe/toast/toast.vcxproj171
-rw-r--r--general/toaster/umdf2/exe/toast/toast.vcxproj.Filters22
-rw-r--r--general/toaster/umdf2/filter/generic/filter.c387
-rw-r--r--general/toaster/umdf2/filter/generic/filter.h85
-rw-r--r--general/toaster/umdf2/filter/generic/filter.rc12
-rw-r--r--general/toaster/umdf2/filter/generic/filterum.inx98
-rw-r--r--general/toaster/umdf2/filter/generic/filterum.vcxproj188
-rw-r--r--general/toaster/umdf2/filter/generic/filterum.vcxproj.Filters34
-rw-r--r--general/toaster/umdf2/func/featured/power.c385
-rw-r--r--general/toaster/umdf2/func/featured/toaster.c862
-rw-r--r--general/toaster/umdf2/func/featured/toaster.rc12
-rw-r--r--general/toaster/umdf2/func/featured/wdffeaturedum.inx98
-rw-r--r--general/toaster/umdf2/func/featured/wdffeaturedum.vcxproj180
-rw-r--r--general/toaster/umdf2/func/featured/wdffeaturedum.vcxproj.Filters42
-rw-r--r--general/toaster/umdf2/func/shared/toaster.h118
-rw-r--r--general/toaster/umdf2/func/simple/toaster.c418
-rw-r--r--general/toaster/umdf2/func/simple/wdfsimpleum.inx97
-rw-r--r--general/toaster/umdf2/func/simple/wdfsimpleum.vcxproj180
-rw-r--r--general/toaster/umdf2/func/simple/wdfsimpleum.vcxproj.Filters34
-rw-r--r--general/toaster/umdf2/inc/driver.h69
-rw-r--r--general/toaster/umdf2/inc/public.h167
-rw-r--r--general/toaster/umdf2/umdf2toaster.sln123
80 files changed, 12101 insertions, 0 deletions
diff --git a/general/toaster/toastpkg/ReadMe.md b/general/toaster/toastpkg/ReadMe.md
new file mode 100644
index 00000000..7a5b7855
--- /dev/null
+++ b/general/toaster/toastpkg/ReadMe.md
@@ -0,0 +1,21 @@
+Toaster Package Sample
+======================
+
+The Toastpkg sample simulates hardware-first and software-first installation of the toaster sample driver.
+
+The Toaster Installation Package comprises driver projects (.vcxproj files) that are contained in the toastpkg.sln solution file (in general/toaster/toastpkg).
+
+This document discusses the different approaches that end users take when adding new hardware to their computer, and describes an approach that addresses these scenarios in a consistent, robust manner. It also outlines the mechanisms provided to facilitate additional vendor requirements such as the installation of value-added software.
+
+**Introduction**
+
+The installation of software to support an instance of a given device (known as "device installation" or "driver installation") is done in a device-centric fashion in Windows operating systems. A device INF that matches up with one of the device's hardware or compatible IDs is used to identify the required driver file(s), registry modifications, etc., that are needed to make the device fully operational. This INF, along with the files copied thereby and a catalog that contains the digital signatures of the INF and these other files, constitute what is known as a "driver package".
+
+Because device installation is done for a specific instance of a device, the "natural" method of adding devices to a computer running a Plug and Play operating system is by plugging in the device first, letting Plug and Play find the device and automatically initiate an installation for that device. The device installation may then proceed using a driver package supplied with the OS, or a "3rd-party" driver package (supplied via CD-ROM, the Internet, or some other distribution mechanism). When the device installation is initiated by the addition of hardware, this is termed a "hardware-first" device installation.
+
+Users may, however, take an alternate approach to adding hardware to their computer. In this scenario, they first run a setup program (perhaps launched as an autorun application when the vendor-supplied CD-ROM is inserted). This setup program may perform installation activities, and then prompt the user to insert their hardware. Upon the hardware's insertion, the vendor-supplied driver package (which was "pre-installed" by the setup program) is then found by Plug and Play, and the installation proceeds as in the hardware-first scenario. When the device installation is initiated by running a setup program, this is termed a "software-first" device installation. This approach to adding new hardware is just as valid as the hardware-first scenario, and some vendors may even instruct their users (via documentation that ships with the hardware) that this is the preferred method.
+
+Vendors must support the hardware-first scenario (by providing a driver package that may be supplied to the "Found New Hardware" wizard with no "pre-configuration" performed by a setup program or other mechanism). Vendors may optionally support the software-first scenario as well, but the actual installation of the device instance is done by Plug and Play upon the device's arrival, as described above.
+
+Vendors may also wish to perform additional activities as part of the device installation. For example, the vendor may want to allow the user to optionally install one or more applications that ship with the device (e.g., a scanner that ships with an image processing application). Such software is termed "value-added software". Value-added software is distinct from the files that comprise the driver package because, unlike the core driver files, the device does not require value-added software to function properly. In the previous example of a scanner, for instance, perhaps the user already has an image processing application that they prefer. The user should be given the option of whether or not they want to install any value-added software. Additional activities (such as allowing the user to select value-added software offerings) may be accomplished by using a vendor-supplied device-specific co-installer.
+
diff --git a/general/toaster/toastpkg/inf/autorun.inf b/general/toaster/toastpkg/inf/autorun.inf
new file mode 100644
index 00000000..4c582d7b
--- /dev/null
+++ b/general/toaster/toastpkg/inf/autorun.inf
@@ -0,0 +1,15 @@
+[AutoRun]
+open=i386\toastva.exe
+icon=i386\toastva.exe,0
+
+[AutoRun.i386]
+open=i386\toastva.exe
+
+[AutoRun.ia64]
+open=ia64\toastva.exe
+
+[AutoRun.amd64]
+open=amd64\toastva.exe
+
+[DeviceInstall]
+DriverPath=\
diff --git a/general/toaster/toastpkg/inf/toastpkg.inf b/general/toaster/toastpkg/inf/toastpkg.inf
new file mode 100644
index 00000000..f427ae87
--- /dev/null
+++ b/general/toaster/toastpkg/inf/toastpkg.inf
@@ -0,0 +1,137 @@
+;/*++
+;
+;Copyright (c) Microsoft Corporation. All rights reserved.
+;
+; THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+; KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+; PURPOSE.
+;
+;Module Name:
+;
+; TOASTPKG.INF
+;
+;Abstract:
+;
+; INF file for installing toaster device drivers (and, optionally, value-
+; added software) via device-specific coinstaller.
+; This is a mutlios INF file. Same INF file cab be used on
+; x86, ia64 and amd64 platforms.
+;
+;--*/
+[Version]
+Signature="$WINDOWS NT$"
+Class=TOASTER
+ClassGuid={B85B7C50-6A01-11d2-B841-00C04FAD5171}
+Provider=%ToastRUs%
+DriverVer=09/21/2006,6.0.5736.1
+CatalogFile.NTx86 = tostx86.cat
+CatalogFile.NTIA64 = tostia64.cat
+CatalogFile.NTAMD64 = tstamd64.cat
+
+[DestinationDirs]
+DefaultDestDir = 12
+CoInstaller_CopyFiles = 11
+ToasterClassInstallerCopyFiles = 11
+
+; ================= Class section =====================
+
+[ClassInstall32]
+Addreg=ToasterClassReg
+CopyFiles=ToasterClassInstallerCopyFiles
+
+[ToasterClassReg]
+HKR,,,0,%ClassName%
+HKR,,Icon,,100
+HKR,,Installer32,,"tostrcls.dll,ToasterClassInstaller"
+HKR,,DeviceCharacteristics,0x10001,0x100 ; Use same security checks on relative opens
+
+[ToasterClassInstallerCopyFiles]
+tostrcls.dll
+
+;*****************************************
+; Toaster Device Install Section
+;*****************************************
+
+[Manufacturer]
+%ToastRUs%=ToastRUs,NTx86, NTia64, NTamd64
+
+; For Win2K
+[ToastRUs]
+%ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster
+
+; For XP and later
+[ToastRUs.NTx86]
+%ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster
+
+[ToastRUs.NTia64]
+%ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster
+
+[ToastRUs.NTamd64]
+%ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster
+
+
+[Toaster_Device.NT]
+CopyFiles=Toaster_Device.NT.Copy
+FriendlyNameFormat=%FriendlyNameFormat%
+
+[Toaster_Device.NT.Copy]
+toaster.sys
+
+[Toaster_Device.NT.HW]
+AddReg=Toaster_Device.NT.HW.AddReg
+
+[Toaster_Device.NT.HW.AddReg]
+HKR,,"BeepCount",0x00010003,4
+
+;-------------- Service installation
+
+[Toaster_Device.NT.Services]
+AddService = toaster, %SPSVCINST_ASSOCSERVICE%, toaster_Service_Inst
+
+[toaster_Service_Inst]
+DisplayName = %toaster.SVCDESC%
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER
+StartType = 3 ; SERVICE_DEMAND_START
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL
+ServiceBinary = %12%\toaster.sys
+
+;-------------- Coinstaller installation
+
+[Toaster_Device.NT.CoInstallers]
+AddReg=CoInstaller_AddReg
+CopyFiles=CoInstaller_CopyFiles
+
+[CoInstaller_CopyFiles]
+tostrco2.dll
+
+[CoInstaller_AddReg]
+HKR,,CoInstallers32,0x00010000,"tostrco2.dll,ToasterCoInstaller"
+
+[ToastCoInfo]
+; Used by the toaster co-installer to figure out where the original media is
+; located (so it can launch value-added setup programs).
+OriginalInfSourcePath = %1%
+
+[SourceDisksNames.x86]
+1 = %DiskId1%, toastpkg.tag,,\i386
+
+[SourceDisksNames.ia64]
+1 = %DiskId1%, toastpkg.tag,,\ia64
+
+[SourceDisksNames.amd64]
+1 = %DiskId1%, toastpkg.tag,,\amd64
+
+[SourceDisksFiles]
+toaster.sys = 1,,
+tostrco2.dll = 1,,
+tostrcls.dll = 1,,
+
+[Strings]
+SPSVCINST_ASSOCSERVICE= 0x00000002
+ToastRUs = "Toast'R'Us"
+ClassName = "Toaster"
+DiskId1 = "Toaster Device Installation Disk #1"
+ToasterDevice.DeviceDesc = "Toaster Package Sample Toaster"
+toaster.SVCDESC = "Microsoft Toaster Device Driver"
+FriendlyNameFormat = "ToasterDevice%1!u!"
diff --git a/general/toaster/toastpkg/toastapp/precomp.h b/general/toaster/toastpkg/toastapp/precomp.h
new file mode 100644
index 00000000..c71537ea
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/precomp.h
@@ -0,0 +1,21 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ precomp.h
+
+Abstract:
+
+ Single container to facilitate use of precompiled headers.
+
+--*/
+
+#include "toastapp.h"
+#include <strsafe.h> \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastapp/precompsrc.c b/general/toaster/toastpkg/toastapp/precompsrc.c
new file mode 100644
index 00000000..5944cf51
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/precompsrc.c
@@ -0,0 +1 @@
+#include "precomp.h" \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastapp/rc_ids.h b/general/toaster/toastpkg/toastapp/rc_ids.h
new file mode 100644
index 00000000..fd47a4c0
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/rc_ids.h
@@ -0,0 +1,22 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ rc_ids.h
+
+Abstract:
+
+ Resource IDs used by the TOASTAPP sample application.
+
+--*/
+
+#define IDD_DEVICE_INTERFACES 1
+#define IDC_DEVICE_INTERFACE_LIST 2
+
diff --git a/general/toaster/toastpkg/toastapp/toastapp.c b/general/toaster/toastpkg/toastapp/toastapp.c
new file mode 100644
index 00000000..d7eaebf3
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/toastapp.c
@@ -0,0 +1,813 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ toastapp.c
+
+Abstract:
+
+ TOASTAPP is an application that provides an automatically updated list of
+ all currently available "toaster" devices (as enumerated by the toaster
+ sample in the Windows 2000 and Windows XP DDKs).
+
+ The toasters' friendly names, along with their pathnames (i.e., for use
+ with CreateFile) are displayed in the dialog box.
+
+Notes:
+
+ For a complete description of device interfaces and PnP event notification,
+ please see the Microsoft Windows 2000/Windows XP DDK and SDK Documentation.
+
+--*/
+
+#include "precomp.h"
+#pragma hdrstop
+
+//
+// Instantiate toaster device interface class GUID (from DDK toaster sample,
+// src\general\toaster\bus\common.h)
+//
+// {781EF630-72B2-11d2-B852-00C04FAD5171}
+//
+
+#include <initguid.h>
+
+DEFINE_GUID (GUID_TOASTER_INTERFACE, 0x781EF630, 0x72B2, 0x11d2, 0xB8, 0x52, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71);
+
+//
+// Declare a global string buffer to be used when retrieving error text via
+// FormatMessage.
+//
+TCHAR ErrorStringBuffer[1024];
+
+//
+// Define structure used to store device interface dialogbox data.
+//
+typedef struct _DIDLG_DATA {
+ HDEVINFO DeviceInfoSet;
+ HDEVNOTIFY hDevNotify;
+ GUID InterfaceClassGuid;
+} DIDLG_DATA, *PDIDLG_DATA;
+
+//
+// Function prototypes
+//
+INT_PTR
+CALLBACK
+DeviceInterfaceDlgProc(
+ _In_ HWND hwnd,
+ _In_ UINT msg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ );
+
+BOOL
+FillInDeviceInterfaceListBox(
+ _In_ HWND hWnd,
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ CONST GUID *InterfaceClassGuid
+ );
+
+BOOL
+GetDeviceInterfaceFriendlyName(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
+ _Out_writes_all_(FriendlyNameSize) PTSTR FriendlyName,
+ _In_ DWORD FriendlyNameSize
+ );
+
+//
+// Implementation
+//
+
+int
+__cdecl
+_tmain(
+ _In_ ULONG argc,
+ _In_reads_(argc) PCHAR argv[]
+ )
+{
+ INT_PTR DlgResult;
+ DIDLG_DATA DIDlgData;
+
+ UNREFERENCED_PARAMETER(argc);
+ UNREFERENCED_PARAMETER(argv);
+
+ //
+ // Initialize our dialogbox data structure.
+ //
+ ZeroMemory(&DIDlgData, sizeof(DIDlgData));
+
+ CopyMemory(&(DIDlgData.InterfaceClassGuid),
+ &GUID_TOASTER_INTERFACE,
+ sizeof(GUID)
+ );
+
+ //
+ // Now fire off the dialog that will present the automatically-updated list
+ // of active device interfaces.
+ //
+ DlgResult = DialogBoxParam(GetModuleHandle(NULL),
+ MAKEINTRESOURCE(IDD_DEVICE_INTERFACES),
+ NULL,
+ DeviceInterfaceDlgProc,
+ (LPARAM)&DIDlgData
+ );
+ if(!DlgResult) {
+ if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ 0,
+ ErrorStringBuffer,
+ sizeof(ErrorStringBuffer) / sizeof(TCHAR),
+ NULL)) {
+
+ _tprintf(TEXT("%s"), ErrorStringBuffer);
+ }
+ return -1;
+
+ } else {
+ return 0;
+ }
+}
+
+
+INT_PTR
+CALLBACK
+DeviceInterfaceDlgProc(
+ _In_ HWND hWnd,
+ _In_ UINT msg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+
+/*++
+
+Routine Description:
+
+ This is the dialog procedure for the device interface dialog box that
+ presents an automatically-updated list of active device interfaces.
+
+ It expects to get an lParam during WM_INITDIALOG that is a pointer to a
+ DIDLGDATA structure where the InterfaceClassGuid field is initialized to
+ the interface class GUID for which the device interface list is to be
+ displayed. (The other fields in this structure are initialized, used, and
+ destroyed during the lifetime of the dialogbox.)
+
+--*/
+
+{
+ PDIDLG_DATA DIDlgData;
+ DWORD Err;
+ PDEV_BROADCAST_DEVICEINTERFACE DevBroadcastDeviceInterface;
+ SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
+
+ if(msg == WM_INITDIALOG) {
+
+ DEV_BROADCAST_DEVICEINTERFACE NotificationFilter;
+ HDEVINFO NewDeviceInfoSet;
+
+ DIDlgData = (PDIDLG_DATA)lParam;
+
+ //
+ // Create a device information set that will be the container for our
+ // device interfaces.
+ //
+ DIDlgData->DeviceInfoSet = SetupDiCreateDeviceInfoList(NULL, NULL);
+
+ if(DIDlgData->DeviceInfoSet == INVALID_HANDLE_VALUE) {
+ Err = GetLastError();
+ _tprintf(TEXT("SetupDiCreateDeviceInfoList failed with %lx\n"), Err);
+ goto clean0;
+ }
+
+ //
+ // Now register to begin receiving notifications for the comings
+ // and goings of device interfaces which are members of the
+ // interface class whose GUID was passed in as the lParam to this
+ // dialog procedure.
+ //
+ ZeroMemory(&NotificationFilter, sizeof(NotificationFilter));
+ NotificationFilter.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE);
+ NotificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
+ CopyMemory(&(NotificationFilter.dbcc_classguid), &(DIDlgData->InterfaceClassGuid), sizeof(GUID));
+
+ DIDlgData->hDevNotify = RegisterDeviceNotification(hWnd,
+ &NotificationFilter,
+ DEVICE_NOTIFY_WINDOW_HANDLE
+ );
+ if(!DIDlgData->hDevNotify) {
+ Err = GetLastError();
+ _tprintf(TEXT("RegisterDeviceNotification failed with %lx\n"), Err);
+ goto clean1;
+ }
+
+ //
+ // OK, now we can retrieve the existing list of active device
+ // interfaces into the device information set we created above.
+ //
+ NewDeviceInfoSet = SetupDiGetClassDevsEx(&(DIDlgData->InterfaceClassGuid),
+ NULL,
+ NULL,
+ DIGCF_PRESENT | DIGCF_DEVICEINTERFACE,
+ DIDlgData->DeviceInfoSet,
+ NULL,
+ NULL
+ );
+
+ if(NewDeviceInfoSet == INVALID_HANDLE_VALUE) {
+ Err = GetLastError();
+ _tprintf(TEXT("SetupDiGetClassDevsEx failed with %lx\n"), Err);
+ goto clean2;
+ }
+
+ //
+ // If SetupDiGetClassDevsEx succeeds and it was passed in an
+ // existing device information set to be used, then the HDEVINFO
+ // it returns is the same as the one it was passed in. Thus, we
+ // can just use the original DeviceInfoSet handle from here on.
+ //
+
+ //
+ // Now fill in our listbox with the current device interface list.
+ //
+ if(!FillInDeviceInterfaceListBox(hWnd,
+ DIDlgData->DeviceInfoSet,
+ &(DIDlgData->InterfaceClassGuid))) {
+ Err = GetLastError();
+ goto clean2;
+ }
+
+ //
+ // Success! Store away a pointer to our device interface dialog data
+ // structure.
+ //
+ SetWindowLongPtr(hWnd, DWLP_USER, (LONG_PTR)DIDlgData);
+ return TRUE;
+
+ //
+ // Clean-up code for error path...
+ //
+clean2:
+ UnregisterDeviceNotification(DIDlgData->hDevNotify);
+clean1:
+ SetupDiDestroyDeviceInfoList(DIDlgData->DeviceInfoSet);
+clean0:
+ if(FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ HRESULT_FROM_SETUPAPI(Err),
+ 0,
+ ErrorStringBuffer,
+ sizeof(ErrorStringBuffer) / sizeof(TCHAR),
+ NULL)) {
+
+ _tprintf(TEXT("%s"), ErrorStringBuffer);
+ }
+
+ EndDialog(hWnd, 0);
+ SetLastError(Err);
+ return TRUE;
+ } else {
+ //
+ // For the small set of messages that we get before WM_INITDIALOG, we
+ // won't have a devwizdata pointer!
+ //
+ DIDlgData = (PDIDLG_DATA)GetWindowLongPtr(hWnd, DWLP_USER);
+ if(DIDlgData == NULL) {
+ //
+ // If we haven't gotten a WM_INITDIALOG message yet, or if for some
+ // reason we weren't able to retrieve the DIDlgData pointer when we
+ // did, then we simply return FALSE.
+ //
+ return FALSE;
+ }
+ }
+
+ switch(msg) {
+
+ case WM_COMMAND:
+ if(LOWORD(wParam) == IDOK) {
+ //
+ // Clean up and return.
+ //
+ UnregisterDeviceNotification(DIDlgData->hDevNotify);
+ SetupDiDestroyDeviceInfoList(DIDlgData->DeviceInfoSet);
+ SetWindowLongPtr(hWnd, DWLP_USER, 0);
+ EndDialog(hWnd, 1);
+ return TRUE;
+ }
+
+ //
+ // All other WM_COMMAND messages unhandled.
+ //
+ break;
+
+ case WM_DEVICECHANGE:
+ //
+ // All the events we're interested in come with lParam pointing to
+ // a structure headed by a DEV_BROADCAST_HDR. This is denoted by
+ // bit 15 of wParam being set, and bit 14 being clear.
+ //
+ if((wParam & 0xC000) == 0x8000) {
+ //
+ // Make sure that this is a device interface notification...
+ //
+ if(((PDEV_BROADCAST_HDR)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
+ DevBroadcastDeviceInterface = (PDEV_BROADCAST_DEVICEINTERFACE)lParam;
+ } else {
+ //
+ // This isn't a device interface notification. Instead,
+ // it's a broadcasted notification sent for backwards-
+ // compatibility (e.g., DBT_DEVTYP_VOLUME).
+ //
+ break;
+ }
+
+ if(wParam == DBT_DEVICEARRIVAL) {
+ _tprintf(TEXT("Received DBT_DEVICEARRIVAL for %s\n"), DevBroadcastDeviceInterface->dbcc_name);
+ } else if(wParam == DBT_DEVICEREMOVEPENDING) {
+ _tprintf(TEXT("Received DBT_DEVICEREMOVEPENDING for %s\n"), DevBroadcastDeviceInterface->dbcc_name);
+ } else if(wParam == DBT_DEVICEREMOVECOMPLETE) {
+ _tprintf(TEXT("Received DBT_DEVICEREMOVECOMPLETE for %s\n"), DevBroadcastDeviceInterface->dbcc_name);
+ } else {
+ //
+ // Presently, there are no other events that are sent for
+ // device interface notification, thus we should never get
+ // here.
+ //
+ break;
+ }
+
+ } else {
+ //
+ // We received some broadcasted system message we don't care
+ // about (e.g., DBT_QUERYCHANGECONFIG).
+ //
+ break;
+ }
+
+ if(wParam == DBT_DEVICEARRIVAL) {
+ //
+ // Open this new device interface into our device information
+ // set.
+ //
+ if(!SetupDiOpenDeviceInterface(DIDlgData->DeviceInfoSet,
+ DevBroadcastDeviceInterface->dbcc_name,
+ 0,
+ NULL)) {
+ Err = GetLastError();
+ _tprintf(TEXT("SetupDiOpenDeviceInterface failed with %lx\n"), Err);
+ return TRUE;
+ }
+
+ } else {
+ //
+ // First, locate this device interface in our device information
+ // set.
+ //
+ DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+ if(SetupDiOpenDeviceInterface(DIDlgData->DeviceInfoSet,
+ DevBroadcastDeviceInterface->dbcc_name,
+ DIODI_NO_ADD,
+ &DeviceInterfaceData)) {
+
+ if(!SetupDiDeleteDeviceInterfaceData(DIDlgData->DeviceInfoSet,
+ &DeviceInterfaceData)) {
+
+ Err = GetLastError();
+ _tprintf(TEXT("SetupDiDeleteDeviceInterfaceData failed with %lx\n"), Err);
+ return TRUE;
+ }
+ }
+ }
+
+ //
+ // If we get to here, we've successfully added or deleted a
+ // device interface in our device information set. Now go update
+ // our listbox with the new list. (Ignore any errors.)
+ //
+ FillInDeviceInterfaceListBox(hWnd,
+ DIDlgData->DeviceInfoSet,
+ &(DIDlgData->InterfaceClassGuid)
+ );
+
+ return TRUE;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+
+BOOL
+FillInDeviceInterfaceListBox(
+ _In_ HWND hWnd,
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ CONST GUID *InterfaceClassGuid
+ )
+
+/*++
+
+Routine Description:
+
+ This routine fills in the listbox of currently-active device interfaces
+ with their corresponding friendly names and pathnames.
+
+Arguments:
+
+ hWnd - Supplies the window handle of the dialog box containing the device
+ interface listbox to be updated.
+
+ DeviceInfoSet - Supplies a handle to the device information set containing
+ device interfaces to be used in updating the listbox.
+
+ InterfaceClassGuid - Supplies the address of the interface class GUID for
+ the device interfaces to be placed into the listbox.
+
+Return Value:
+
+ If the function succeeds, the return value is non-zero.
+ If the function fails, the return value is FALSE. To find out what the
+ cause of failure was, call GetLastError().
+
+--*/
+
+{
+ DWORD i, Err;
+ SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
+ PTSTR FriendlyName;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
+ PBYTE Buffer;
+ DWORD BufferSize = 0;
+ DWORD RequiredSize;
+ LRESULT ListBoxReturn;
+ size_t FriendlyNameLen;
+ size_t devicePathLen;
+
+ //
+ // Reset the listbox in preparation for adding the current list of device
+ // interfaces.
+ //
+ SendDlgItemMessage(hWnd,
+ IDC_DEVICE_INTERFACE_LIST,
+ LB_RESETCONTENT,
+ 0,
+ 0
+ );
+
+ DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
+ Err = NO_ERROR;
+
+ //
+ // Start out with a buffer that should be large enough to hold the friendly
+ // name plus the device interface detail data for a "reasonably-sized"
+ // device interface pathname. Note that device interface paths aren't
+ // confined to MAX_PATH length on Windows 2000, so we deal with the case
+ // where we may need a larger buffer.
+ //
+ // Note that we add a space and an open paren between the friendly name and
+ // the pathname. We have space for this (even in Unicode), because the
+ // device interface detail data buffer always begins with a DWORD cbSize
+ // field, that we can overwrite, without touching the character DevicePath
+ // buffer.
+ //
+ BufferSize = (LINE_LEN * sizeof(TCHAR)) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)
+ + (MAX_PATH * sizeof(TCHAR));
+
+ Buffer = malloc(BufferSize);
+
+ if(Buffer) {
+ //
+ // Leave the first LINE_LEN characters to retrieve the friendly name
+ // into...
+ //
+ FriendlyName = (PTSTR)Buffer;
+ DeviceInterfaceDetailData =
+ (PSP_DEVICE_INTERFACE_DETAIL_DATA)(Buffer + (LINE_LEN * sizeof(TCHAR)));
+
+ DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+ } else {
+ //
+ // Failure!
+ //
+ _tprintf(TEXT("Couldn't allocate %d bytes for device interface detail buffer\n"),
+ BufferSize
+ );
+
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ for(i = 0;
+ SetupDiEnumDeviceInterfaces(DeviceInfoSet,
+ NULL,
+ InterfaceClassGuid,
+ i,
+ &DeviceInterfaceData);
+ i++) {
+
+ //
+ // To retrieve the device interface name (e.g., that you can call
+ // CreateFile() on...
+ //
+ while(!SetupDiGetDeviceInterfaceDetail(DeviceInfoSet,
+ &DeviceInterfaceData,
+ DeviceInterfaceDetailData,
+ BufferSize - (LINE_LEN * sizeof(TCHAR)),
+ &RequiredSize,
+ NULL)) {
+ //
+ // We failed to get the device interface detail data--was it because
+ // our buffer was too small? (Hopefully so!)
+ //
+ Err = GetLastError();
+
+ //
+ // We can get rid of our current buffer regardless of what the
+ // error was...
+ //
+ free(Buffer);
+ Buffer = NULL;
+
+ if(Err != ERROR_INSUFFICIENT_BUFFER) {
+ //
+ // Failure!
+ //
+ _tprintf(TEXT("SetupDiGetDeviceInterfaceDetail failed with %lx\n"), Err);
+ break;
+ }
+
+ //
+ // We failed due to insufficient buffer. Allocate one that's
+ // sufficiently large and try again.
+ //
+ BufferSize = RequiredSize + (LINE_LEN * sizeof(TCHAR));
+
+ Buffer = malloc(BufferSize);
+
+ if(Buffer) {
+ //
+ // Leave the first LINE_LEN characters to retrieve the friendly
+ // name into...
+ //
+ FriendlyName = (PTSTR)Buffer;
+ DeviceInterfaceDetailData =
+ (PSP_DEVICE_INTERFACE_DETAIL_DATA)(Buffer + (LINE_LEN * sizeof(TCHAR)));
+
+ DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+ Err = NO_ERROR;
+
+ } else {
+ //
+ // Failure!
+ //
+ Err = ERROR_NOT_ENOUGH_MEMORY;
+ _tprintf(TEXT("Couldn't allocate %d bytes for device interface detail buffer\n"), RequiredSize);
+ break;
+ }
+ }
+
+ if(!Buffer) {
+ //
+ // We encountered a failure above--abort.
+ //
+ break;
+ }
+
+ //
+ // Now that we've successfully retrieved the device interface pathname,
+ // we can retrieve the friendly name. We left enough space at the
+ // start of the buffer for this, so we'll now retrieve this string,
+ // then move the pathname down next to it for display (the pathname
+ // will be enclosed in parentheses).
+ //
+ if(!GetDeviceInterfaceFriendlyName(DeviceInfoSet,
+ &DeviceInterfaceData,
+ FriendlyName,
+ LINE_LEN)) {
+ //
+ // This generally won't happen, but it _is_ possible. We'll just
+ // use two double-quotes to indicate an empty string.
+ //
+ if(FAILED(StringCchCopy(FriendlyName, LINE_LEN, TEXT("\"\"")))) {
+ break;
+ }
+ }
+
+ //
+ // Add a space and the opening paren (see previous comment on why we're
+ // safe in doing this without fear of overwriting the DevicePath string.
+ //
+ if(FAILED(StringCchCat(FriendlyName, LINE_LEN, TEXT(" (")))) {
+ break;
+ }
+
+ if(FAILED(StringCchLength(FriendlyName, LINE_LEN, &FriendlyNameLen))) {
+ break;
+ }
+
+ //
+ // Now move the pathname down to the character immediately following
+ // the open paren. (Note: since source and destination blocks may
+ // overlap, we must use MoveMemory.)
+ //
+ if(FAILED(StringCbLength(DeviceInterfaceDetailData->DevicePath,
+ MAX_PATH,
+ &devicePathLen))) {
+ break;
+ }
+
+ devicePathLen += sizeof(TCHAR);
+
+ MoveMemory((PBYTE)(FriendlyName + FriendlyNameLen),
+ DeviceInterfaceDetailData->DevicePath,
+ devicePathLen
+ );
+
+ //
+ // Now add close paren
+ //
+ if (FAILED(StringCchCat(FriendlyName, LINE_LEN, TEXT(")")))) {
+ break;
+ }
+
+ //
+ // Add this device interface to our listbox.
+ //
+ ListBoxReturn = SendDlgItemMessage(hWnd,
+ IDC_DEVICE_INTERFACE_LIST,
+ LB_ADDSTRING,
+ 0,
+ (LPARAM)FriendlyName
+ );
+
+ if((ListBoxReturn == LB_ERR) || (ListBoxReturn == LB_ERRSPACE)) {
+ //
+ // Set Err to some generic failure
+ //
+ Err = ERROR_INVALID_DATA;
+
+ _tprintf(TEXT("Failed to add %s to listbox (%s)\n"),
+ DeviceInterfaceDetailData->DevicePath,
+ (ListBoxReturn == LB_ERR) ? TEXT("LB_ERR") : TEXT("LB_ERRSPACE")
+ );
+ break;
+ }
+
+ //
+ // Since we may have overwritten the device interface detail data
+ // 'cbSize' field, restore it now.
+ //
+ DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
+ }
+
+ if(Buffer) {
+ free(Buffer);
+ }
+
+ SetLastError(Err);
+
+ return (Err == NO_ERROR);
+}
+
+
+BOOL
+GetDeviceInterfaceFriendlyName(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData,
+ _Out_writes_all_(FriendlyNameSize) PTSTR FriendlyName,
+ _In_ DWORD FriendlyNameSize
+ )
+
+/*++
+
+Routine Description:
+
+ This routine retrieves the friendly name associated with the specified
+ device interface. It first looks for a "FriendlyName" value entry in the
+ device interface's registry key. If not found, it then tries to use the
+ "FriendlyName" property for the underlying devnode. If that isn't present,
+ it uses the devnode's device description (and if there isnt one of those,
+ it returns FALSE).
+
+Arguments:
+
+ DeviceInfoSet - Supplies a handle to the device information set containing
+ the device interface whose friendly name is to be retrieved.
+
+ DeviceInterfaceData - Supplies a context structure indicating which device
+ interface we're retrieving a friendly name for.
+
+ FriendlyName - Supplies a character buffer that is filled in, upon
+ successful return, with the friendly name for the device interface.
+
+ FriendlyNameSize - Supplies the size, in characters, of the FriendlyName
+ buffer.
+
+Return Value:
+
+ If the function succeeds, the return value is non-zero.
+ If no FriendlyName is found (or buffer is too small), the return value is
+ FALSE.
+
+--*/
+
+{
+ HKEY hkey;
+ DWORD Err;
+ SP_DEVINFO_DATA DeviceInfoData;
+ DWORD RegDataType, RegDataLength;
+
+ //
+ // First, open up the device interface registry key to see if the interface
+ // has its own friendly name.
+ //
+ hkey = SetupDiOpenDeviceInterfaceRegKey(DeviceInfoSet,
+ DeviceInterfaceData,
+ 0,
+ KEY_READ
+ );
+
+ if(hkey != INVALID_HANDLE_VALUE) {
+
+ RegDataLength = FriendlyNameSize * sizeof(TCHAR);
+
+ Err = RegQueryValueEx(hkey,
+ TEXT("FriendlyName"),
+ NULL,
+ &RegDataType,
+ (PBYTE)FriendlyName,
+ &RegDataLength
+ );
+
+ RegCloseKey(hkey);
+
+ if((Err == ERROR_SUCCESS) && (RegDataType == REG_SZ)) {
+ return TRUE;
+ }
+ }
+
+ //
+ // Find out what device instance is exposing this interface.
+ //
+ DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+ if(!SetupDiGetDeviceInterfaceDetail(DeviceInfoSet,
+ DeviceInterfaceData,
+ NULL,
+ 0,
+ NULL,
+ &DeviceInfoData)) {
+ //
+ // We should always get here (i.e., SetupDiGetDeviceInterfaceDetail
+ // should always fail) since we didn't pass in a buffer to retrieve
+ // the device interface detail data. Of course, all we really care
+ // about is getting at the underlying device info data.
+ //
+
+ //
+ // Now check the underlying device for a FriendlyName property.
+ //
+ if(SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+ &DeviceInfoData,
+ SPDRP_FRIENDLYNAME,
+ &RegDataType,
+ (PBYTE)FriendlyName,
+ FriendlyNameSize * sizeof(TCHAR),
+ NULL)) {
+ if(RegDataType == REG_SZ) {
+ return TRUE;
+ }
+ }
+
+ //
+ // Fall back to device description
+ //
+ if(SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+ &DeviceInfoData,
+ SPDRP_DEVICEDESC,
+ &RegDataType,
+ (PBYTE)FriendlyName,
+ FriendlyNameSize * sizeof(TCHAR),
+ NULL)) {
+ if(RegDataType == REG_SZ) {
+ return TRUE;
+ }
+ }
+ }
+
+ //
+ // Couldn't find anything usable as a friendly name--return failure.
+ //
+ return FALSE;
+}
+
diff --git a/general/toaster/toastpkg/toastapp/toastapp.dlg b/general/toaster/toastpkg/toastapp/toastapp.dlg
new file mode 100644
index 00000000..d3cc1e53
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/toastapp.dlg
@@ -0,0 +1,12 @@
+1 DLGINCLUDE "rc_ids.h"
+
+IDD_DEVICE_INTERFACES DIALOG 82, 80, 412, 215
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+CAPTION "Currently Available Toasters"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LISTBOX IDC_DEVICE_INTERFACE_LIST, 8, 9, 396, 177, LBS_SORT |
+ LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ DEFPUSHBUTTON "OK", IDD_DEVICE_INTERFACES, 181, 195, 50, 14
+END
diff --git a/general/toaster/toastpkg/toastapp/toastapp.h b/general/toaster/toastpkg/toastapp/toastapp.h
new file mode 100644
index 00000000..bf34ba76
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/toastapp.h
@@ -0,0 +1,29 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ toastapp.h
+
+Abstract:
+
+ Header files used by the TOASTAPP sample application.
+
+--*/
+
+#include <windows.h>
+#include <objbase.h>
+#include <setupapi.h>
+#include <dbt.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <tchar.h>
+
+#include "rc_ids.h"
diff --git a/general/toaster/toastpkg/toastapp/toastapp.ico b/general/toaster/toastpkg/toastapp/toastapp.ico
new file mode 100644
index 00000000..55ab969e
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/toastapp.ico
Binary files differ
diff --git a/general/toaster/toastpkg/toastapp/toastapp.rc b/general/toaster/toastpkg/toastapp/toastapp.rc
new file mode 100644
index 00000000..857a81b3
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/toastapp.rc
@@ -0,0 +1,69 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ toastapp.rc
+
+Abstract:
+
+ Resources used by the TOASTAPP sample application.
+
+--*/
+
+#include <windows.h>
+#include <commctrl.h>
+#include "rc_ids.h"
+
+//
+// Version resources
+//
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Microsoft Corporation\0"
+ VALUE "FileDescription", "Toaster Interface Notification Test Application\0"
+ VALUE "FileVersion", "1.00.0000.0\0"
+ VALUE "InternalName", "TOASTAPP.EXE\0"
+ VALUE "LegalCopyright", "� Microsoft Corporation. All rights reserved.\0"
+ VALUE "OriginalFilename", "TOASTAPP.EXE\0"
+ VALUE "ProductName", "Toaster DDK Sample\0"
+ VALUE "ProductVersion", "1.0.0000.0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+//
+// Icon resources
+//
+1 ICON DISCARDABLE "toastapp.ico"
+
+//
+// Dialog resources
+//
+#include "toastapp.dlg"
+
diff --git a/general/toaster/toastpkg/toastapp/toastapp.vcxproj b/general/toaster/toastpkg/toastapp/toastapp.vcxproj
new file mode 100644
index 00000000..9e71f3da
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/toastapp.vcxproj
@@ -0,0 +1,209 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{1C818755-28B2-4C84-8623-FF84F3326B64}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{42007D8E-51B7-469B-B5D0-45C7674BFFEF}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>toastapp</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>toastapp</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>toastapp</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>toastapp</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="toastapp.c">
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ResourceCompile Include="toastapp.rc" />
+ </ItemGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="precompsrc.c">
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Create</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastapp/toastapp.vcxproj.Filters b/general/toaster/toastpkg/toastapp/toastapp.vcxproj.Filters
new file mode 100644
index 00000000..bcbb10b1
--- /dev/null
+++ b/general/toaster/toastpkg/toastapp/toastapp.vcxproj.Filters
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{5B7E141F-3C1C-446C-B423-22D8F13BD05C}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{21C18B76-71F9-4B0C-B377-B15E4821D9CD}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{67F5F556-F3BD-4452-88F3-806BDB94EB5F}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="precompsrc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="toastapp.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="toastapp.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastcd/ToastApp/setup.ini b/general/toaster/toastpkg/toastcd/ToastApp/setup.ini
new file mode 100644
index 00000000..81d61154
--- /dev/null
+++ b/general/toaster/toastpkg/toastcd/ToastApp/setup.ini
Binary files differ
diff --git a/general/toaster/toastpkg/toastcd/ToastApp/toastapp.msi b/general/toaster/toastpkg/toastcd/ToastApp/toastapp.msi
new file mode 100644
index 00000000..0bdfaa65
--- /dev/null
+++ b/general/toaster/toastpkg/toastcd/ToastApp/toastapp.msi
Binary files differ
diff --git a/general/toaster/toastpkg/toastcd/amd64/toaster.sys b/general/toaster/toastpkg/toastcd/amd64/toaster.sys
new file mode 100644
index 00000000..d51da6c4
--- /dev/null
+++ b/general/toaster/toastpkg/toastcd/amd64/toaster.sys
Binary files differ
diff --git a/general/toaster/toastpkg/toastcd/autorun.inf b/general/toaster/toastpkg/toastcd/autorun.inf
new file mode 100644
index 00000000..4c582d7b
--- /dev/null
+++ b/general/toaster/toastpkg/toastcd/autorun.inf
@@ -0,0 +1,15 @@
+[AutoRun]
+open=i386\toastva.exe
+icon=i386\toastva.exe,0
+
+[AutoRun.i386]
+open=i386\toastva.exe
+
+[AutoRun.ia64]
+open=ia64\toastva.exe
+
+[AutoRun.amd64]
+open=amd64\toastva.exe
+
+[DeviceInstall]
+DriverPath=\
diff --git a/general/toaster/toastpkg/toastcd/i386/toaster.sys b/general/toaster/toastpkg/toastcd/i386/toaster.sys
new file mode 100644
index 00000000..19184dc9
--- /dev/null
+++ b/general/toaster/toastpkg/toastcd/i386/toaster.sys
Binary files differ
diff --git a/general/toaster/toastpkg/toastcd/toastpkg.inf b/general/toaster/toastpkg/toastcd/toastpkg.inf
new file mode 100644
index 00000000..f427ae87
--- /dev/null
+++ b/general/toaster/toastpkg/toastcd/toastpkg.inf
@@ -0,0 +1,137 @@
+;/*++
+;
+;Copyright (c) Microsoft Corporation. All rights reserved.
+;
+; THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+; KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+; PURPOSE.
+;
+;Module Name:
+;
+; TOASTPKG.INF
+;
+;Abstract:
+;
+; INF file for installing toaster device drivers (and, optionally, value-
+; added software) via device-specific coinstaller.
+; This is a mutlios INF file. Same INF file cab be used on
+; x86, ia64 and amd64 platforms.
+;
+;--*/
+[Version]
+Signature="$WINDOWS NT$"
+Class=TOASTER
+ClassGuid={B85B7C50-6A01-11d2-B841-00C04FAD5171}
+Provider=%ToastRUs%
+DriverVer=09/21/2006,6.0.5736.1
+CatalogFile.NTx86 = tostx86.cat
+CatalogFile.NTIA64 = tostia64.cat
+CatalogFile.NTAMD64 = tstamd64.cat
+
+[DestinationDirs]
+DefaultDestDir = 12
+CoInstaller_CopyFiles = 11
+ToasterClassInstallerCopyFiles = 11
+
+; ================= Class section =====================
+
+[ClassInstall32]
+Addreg=ToasterClassReg
+CopyFiles=ToasterClassInstallerCopyFiles
+
+[ToasterClassReg]
+HKR,,,0,%ClassName%
+HKR,,Icon,,100
+HKR,,Installer32,,"tostrcls.dll,ToasterClassInstaller"
+HKR,,DeviceCharacteristics,0x10001,0x100 ; Use same security checks on relative opens
+
+[ToasterClassInstallerCopyFiles]
+tostrcls.dll
+
+;*****************************************
+; Toaster Device Install Section
+;*****************************************
+
+[Manufacturer]
+%ToastRUs%=ToastRUs,NTx86, NTia64, NTamd64
+
+; For Win2K
+[ToastRUs]
+%ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster
+
+; For XP and later
+[ToastRUs.NTx86]
+%ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster
+
+[ToastRUs.NTia64]
+%ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster
+
+[ToastRUs.NTamd64]
+%ToasterDevice.DeviceDesc%=Toaster_Device, {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster
+
+
+[Toaster_Device.NT]
+CopyFiles=Toaster_Device.NT.Copy
+FriendlyNameFormat=%FriendlyNameFormat%
+
+[Toaster_Device.NT.Copy]
+toaster.sys
+
+[Toaster_Device.NT.HW]
+AddReg=Toaster_Device.NT.HW.AddReg
+
+[Toaster_Device.NT.HW.AddReg]
+HKR,,"BeepCount",0x00010003,4
+
+;-------------- Service installation
+
+[Toaster_Device.NT.Services]
+AddService = toaster, %SPSVCINST_ASSOCSERVICE%, toaster_Service_Inst
+
+[toaster_Service_Inst]
+DisplayName = %toaster.SVCDESC%
+ServiceType = 1 ; SERVICE_KERNEL_DRIVER
+StartType = 3 ; SERVICE_DEMAND_START
+ErrorControl = 1 ; SERVICE_ERROR_NORMAL
+ServiceBinary = %12%\toaster.sys
+
+;-------------- Coinstaller installation
+
+[Toaster_Device.NT.CoInstallers]
+AddReg=CoInstaller_AddReg
+CopyFiles=CoInstaller_CopyFiles
+
+[CoInstaller_CopyFiles]
+tostrco2.dll
+
+[CoInstaller_AddReg]
+HKR,,CoInstallers32,0x00010000,"tostrco2.dll,ToasterCoInstaller"
+
+[ToastCoInfo]
+; Used by the toaster co-installer to figure out where the original media is
+; located (so it can launch value-added setup programs).
+OriginalInfSourcePath = %1%
+
+[SourceDisksNames.x86]
+1 = %DiskId1%, toastpkg.tag,,\i386
+
+[SourceDisksNames.ia64]
+1 = %DiskId1%, toastpkg.tag,,\ia64
+
+[SourceDisksNames.amd64]
+1 = %DiskId1%, toastpkg.tag,,\amd64
+
+[SourceDisksFiles]
+toaster.sys = 1,,
+tostrco2.dll = 1,,
+tostrcls.dll = 1,,
+
+[Strings]
+SPSVCINST_ASSOCSERVICE= 0x00000002
+ToastRUs = "Toast'R'Us"
+ClassName = "Toaster"
+DiskId1 = "Toaster Device Installation Disk #1"
+ToasterDevice.DeviceDesc = "Toaster Package Sample Toaster"
+toaster.SVCDESC = "Microsoft Toaster Device Driver"
+FriendlyNameFormat = "ToasterDevice%1!u!"
diff --git a/general/toaster/toastpkg/toastcd/toastpkg.tag b/general/toaster/toastpkg/toastcd/toastpkg.tag
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/general/toaster/toastpkg/toastcd/toastpkg.tag
diff --git a/general/toaster/toastpkg/toastcd/tostx86.cat b/general/toaster/toastpkg/toastcd/tostx86.cat
new file mode 100644
index 00000000..31450f2f
--- /dev/null
+++ b/general/toaster/toastpkg/toastcd/tostx86.cat
Binary files differ
diff --git a/general/toaster/toastpkg/toastcd/tstamd64.cat b/general/toaster/toastpkg/toastcd/tstamd64.cat
new file mode 100644
index 00000000..f91fe53f
--- /dev/null
+++ b/general/toaster/toastpkg/toastcd/tstamd64.cat
Binary files differ
diff --git a/general/toaster/toastpkg/toastco/precomp.h b/general/toaster/toastpkg/toastco/precomp.h
new file mode 100644
index 00000000..2b688022
--- /dev/null
+++ b/general/toaster/toastpkg/toastco/precomp.h
@@ -0,0 +1,21 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ precomp.h
+
+Abstract:
+
+ Single container to facilitate use of precompiled headers.
+
+--*/
+
+#include "toastco.h"
+#include <strsafe.h>
diff --git a/general/toaster/toastpkg/toastco/precompsrc.c b/general/toaster/toastpkg/toastco/precompsrc.c
new file mode 100644
index 00000000..5944cf51
--- /dev/null
+++ b/general/toaster/toastpkg/toastco/precompsrc.c
@@ -0,0 +1 @@
+#include "precomp.h" \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastco/toastco.c b/general/toaster/toastpkg/toastco/toastco.c
new file mode 100644
index 00000000..a66b07ac
--- /dev/null
+++ b/general/toaster/toastpkg/toastco/toastco.c
@@ -0,0 +1,1312 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ toastco.c
+
+Abstract:
+
+ Device-specific co-installer for the Toaster Package sample.
+
+--*/
+
+#include "precomp.h"
+#pragma hdrstop
+
+//
+// Constants
+//
+#define TOASTAPP_SETUP_SUBDIR L"ToastApp"
+#define TOASTAPP_SETUP_EXE L"\\setup.exe"
+#define TOASTAPP_SETUP_PATH (TOASTAPP_SETUP_SUBDIR TOASTAPP_SETUP_EXE)
+
+#define TOASTER_MEDIA_SOURCE_ID 1
+
+//
+// Globals
+//
+HMODULE g_hInstance;
+WCHAR SetupExeName[] = TOASTAPP_SETUP_EXE;
+
+//
+// Structures
+//
+typedef struct _VALUEADDWIZDATA {
+ BOOL AppInstallAttempted; // Have we previously attempted to install app?
+ WCHAR MediaRootDirectory[MAX_PATH]; // Fully-qualified path to root of install media
+ WCHAR MediaDiskName[LINE_LEN]; // Name of media to prompt for (or empty string)
+ WCHAR MediaTagFile[MAX_PATH]; // Tagfile identifying removable media (or empty string)
+} VALUEADDWIZDATA, *LPVALUEADDWIZDATA;
+
+//
+// Function prototypes
+//
+INT_PTR
+CALLBACK
+ValueAddDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ );
+
+BOOL
+InstallToastApp(
+ _In_ HWND hwndDlg,
+ _In_ LPCWSTR MediaRootDirectory
+ );
+
+UINT
+ValueAddPropSheetPageProc(
+ _In_ HWND hwnd,
+ _In_ UINT uMsg,
+ _In_ LPPROPSHEETPAGE ppsp
+ );
+
+_Success_(return == TRUE)
+BOOL
+GetMediaRootDirectory(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVINFO_DATA DeviceInfoData,
+ _Out_ LPWSTR *MediaRootDirectory,
+ _Outptr_result_maybenull_ LPWSTR *MediaDiskName,
+ _Outptr_result_maybenull_ LPWSTR *MediaTagFile
+ );
+
+HPROPSHEETPAGE
+GetValueAddSoftwareWizPage(
+ _In_ LPCWSTR MediaRootDirectory,
+ _In_opt_ LPCWSTR MediaDiskName,
+ _In_opt_ LPCWSTR MediaTagFile
+ );
+
+VOID
+SetDeviceFriendlyName(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVINFO_DATA DeviceInfoData
+ );
+
+//
+// Implementation
+//
+
+BOOL WINAPI
+DllMain(
+ _In_ HINSTANCE hInstDll,
+ _In_ DWORD Reason,
+ _In_ LPVOID Reserved
+ )
+
+/*++
+
+Routine Description:
+
+ Initialization/de-initialization entry point for toastco.dll
+
+Arguments:
+
+ hInstDll - Supplies handle to the DLL module
+
+ Reason - Supplies the reason for calling the function
+
+ pctx - Reserved
+
+Return Value:
+
+ This function always returns TRUE.
+
+--*/
+
+{
+ UNREFERENCED_PARAMETER(Reserved);
+
+ switch(Reason) {
+
+ case DLL_PROCESS_ATTACH:
+ g_hInstance = hInstDll;
+ break;
+
+ case DLL_PROCESS_DETACH:
+ g_hInstance = NULL;
+ break;
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+
+DWORD CALLBACK
+ToasterCoInstaller(
+ _In_ DI_FUNCTION InstallFunction,
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVINFO_DATA DeviceInfoData OPTIONAL,
+ _Inout_ PCOINSTALLER_CONTEXT_DATA Context
+ )
+
+/*++
+
+Routine Description:
+
+ This function acts as a device-specific co-installer for "toaster" devices.
+
+Arguments:
+
+ InstallFunction - Specifies the device installer function code indicating
+ the action being performed.
+
+ DeviceInfoSet - Supplies a handle to the device information set being
+ acted upon by this install action.
+
+ DeviceInfoData - Optionally, supplies the address of a device information
+ element being acted upon by this install action.
+
+ Context - Supplies the installation context that is per-install request/
+ per-coinstaller.
+
+Return Value:
+
+ If this function successfully completed the requested action (or did
+ nothing) and wishes for the installation to continue, the return value
+ is NO_ERROR.
+
+ If this function successfully completed the requested action (or did
+ nothing) and would like to be called back once installation has
+ completed, the return value is ERROR_DI_POSTPROCESSING_REQUIRED.
+
+ If an error occurred while attempting to perform the requested action, a
+ Win32 error code is returned. The install action will be aborted.
+
+--*/
+
+{
+ SP_NEWDEVICEWIZARD_DATA NewDeviceWizardData;
+ HKEY hKey;
+ DWORD Err;
+ DWORD RegDataType;
+ DWORD RequiredSize;
+ DWORD UserPrompted;
+ PWSTR MediaRootDirectory, MediaDiskName, MediaTagFile;
+
+ UNREFERENCED_PARAMETER( Context );
+
+ switch(InstallFunction) {
+
+ case DIF_INSTALLDEVICE:
+ //
+ // In version 1 of our coinstaller, we had a hard-coded format
+ // for the device's FriendlyName. This wasn't a localizable
+ // solution. Now, we retrieve a (localized) format string from
+ // the device INF.
+ //
+ // We should always get called with a valid DeviceInfoData, but
+ // just to be sure...
+ //
+ if(DeviceInfoData != NULL) {
+ SetDeviceFriendlyName(DeviceInfoSet, DeviceInfoData);
+ }
+
+ break;
+
+ case DIF_NEWDEVICEWIZARD_FINISHINSTALL:
+ //
+ // We should always get called with a valid DeviceInfoData, but
+ // just in case we don't we will bail out right away.
+ //
+ if(DeviceInfoData == NULL) {
+ break;
+ }
+
+ //
+ // Only supply a finish-install wizard page the first time...
+ //
+ if(ERROR_SUCCESS != RegOpenKeyEx(
+ HKEY_LOCAL_MACHINE,
+ TEXT("SOFTWARE\\Microsoft\\Toaster"),
+ 0,
+ KEY_READ,
+ &hKey)) {
+ //
+ // If we can't open this key, then we can't ascertain whether
+ // or not the user was previously prompted to select value-add
+ // software. Assume they haven't been (i.e., this is the first
+ // time, so the key doesn't exist yet).
+ //
+ UserPrompted = 0;
+
+ } else {
+ //
+ // Look for non-zero "User Prompted" value entry to indicate
+ // that the user has previously responded to question about
+ // installation of value-add software.
+ //
+ RequiredSize = sizeof(UserPrompted);
+
+ Err = RegQueryValueEx(hKey,
+ TEXT("User Prompted"),
+ NULL,
+ &RegDataType,
+ (PBYTE)&UserPrompted,
+ &RequiredSize
+ );
+
+ if(Err != ERROR_SUCCESS) {
+ UserPrompted = 0;
+ }
+
+ RegCloseKey(hKey);
+ }
+
+ if(UserPrompted) {
+ //
+ // We asked the user this question before--don't bother them
+ // again.
+ //
+ break;
+ }
+
+ //
+ // It's possible that we could return the handle of our finish
+ // install wizard page, yet it might never be used (e.g., if we're
+ // in a server-side installation). Thus, we won't set our
+ // "User Prompted" registry flag just yet. We'll wait until the
+ // user actually sees this page before setting the flag.
+ //
+
+ ZeroMemory(&NewDeviceWizardData, sizeof(NewDeviceWizardData));
+ NewDeviceWizardData.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
+
+ if(SetupDiGetClassInstallParams(DeviceInfoSet,
+ DeviceInfoData,
+ (PSP_CLASSINSTALL_HEADER)&NewDeviceWizardData,
+ sizeof(SP_NEWDEVICEWIZARD_DATA),
+ NULL)) {
+ //
+ // First, make sure there's room for us to add a page...
+ //
+ if(NewDeviceWizardData.NumDynamicPages >= MAX_INSTALLWIZARD_DYNAPAGES) {
+ break;
+ }
+
+ //
+ // Retrieve the location of the source media based on the INF
+ // we're installing from.
+ //
+ if(!GetMediaRootDirectory(DeviceInfoSet,
+ DeviceInfoData,
+ &MediaRootDirectory,
+ &MediaDiskName,
+ &MediaTagFile)) {
+ //
+ // We couldn't figure out where the source media is, so we
+ // can't offer any value-added software to the user.
+ //
+ break;
+ }
+
+ NewDeviceWizardData.DynamicPages[NewDeviceWizardData.NumDynamicPages] =
+ GetValueAddSoftwareWizPage(MediaRootDirectory,
+ MediaDiskName,
+ MediaTagFile
+ );
+
+ //
+ // We don't need the media strings any more.
+ //
+ GlobalFree(MediaRootDirectory);
+
+ if(MediaDiskName) {
+ GlobalFree(MediaDiskName);
+ }
+
+ if(MediaTagFile) {
+ GlobalFree(MediaTagFile);
+ }
+
+ if(NewDeviceWizardData.DynamicPages[NewDeviceWizardData.NumDynamicPages] != NULL) {
+ NewDeviceWizardData.NumDynamicPages++;
+ }
+
+ SetupDiSetClassInstallParams(DeviceInfoSet,
+ DeviceInfoData,
+ (PSP_CLASSINSTALL_HEADER)&NewDeviceWizardData,
+ sizeof(SP_NEWDEVICEWIZARD_DATA)
+ );
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ return NO_ERROR;
+}
+
+
+BOOL
+InstallToastApp(
+ _In_ HWND hwndWizard,
+ _In_ LPCWSTR FullSetupPath
+ )
+
+/*++
+
+Routine Description:
+
+ This routine hides the wizard, kicks off the ToastApp setup program, then
+ unhides the wizard when the ToastApp setup process terminates.
+
+Arguments:
+
+ hwndWizard - Handle to the wizard window to be hidden.
+
+ FullSetupPath - Supplies the path to the setup program to be launched.
+
+Return Value:
+
+ If the setup app was successfully launched, the return value is TRUE.
+ Otherwise, it is FALSE.
+
+--*/
+
+{
+ BOOL b;
+ STARTUPINFO StartupInfo;
+ PROCESS_INFORMATION ProcessInformation;
+
+ //
+ // Hide our wizard for the duration of the Toaster app's installation...
+ //
+ ShowWindow(hwndWizard, SW_HIDE);
+ GetStartupInfo(&StartupInfo);
+
+ b = CreateProcess(FullSetupPath,
+ NULL,
+ NULL,
+ NULL,
+ FALSE,
+ DETACHED_PROCESS | NORMAL_PRIORITY_CLASS,
+ NULL,
+ NULL,
+ &StartupInfo,
+ &ProcessInformation
+ );
+
+ if(b) {
+ //
+ // Don't need a handle to the thread...
+ //
+ CloseHandle(ProcessInformation.hThread);
+
+ //
+ // ...but we _do_ want to wait on the process handle.
+ //
+ WaitForMultipleObjects(1, &ProcessInformation.hProcess, FALSE, INFINITE);
+
+ CloseHandle(ProcessInformation.hProcess);
+ }
+
+ //
+ // Now show our wizard once again...
+ //
+ ShowWindow(hwndWizard, SW_SHOW);
+
+ return b;
+}
+
+
+UINT
+ValueAddPropSheetPageProc(
+ _In_ HWND hwnd,
+ _In_ UINT uMsg,
+ _In_ LPPROPSHEETPAGE ppsp
+ )
+
+/*++
+
+Routine Description:
+
+ This function is the property sheet page procedure, used to free the
+ context data associated with the page when it is released.
+
+Arguments:
+
+ hwnd - Supplies a handle to the property page window
+
+ uMsg - Supplies the message identifying the action being taken
+
+ ppsp - Supplies the PROPSHEETPAGE structure for our page
+
+Return Value:
+
+ This routine always return non-zero (1).
+
+--*/
+
+{
+ UNREFERENCED_PARAMETER(hwnd);
+
+ switch(uMsg) {
+
+ case PSPCB_RELEASE :
+ GlobalFree((LPVALUEADDWIZDATA)(ppsp->lParam));
+ break;
+
+ default :
+ break;
+ }
+
+ return 1; // let the page be created (return ignored on page release)
+}
+
+
+INT_PTR
+CALLBACK
+ValueAddDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+
+/*++
+
+Routine Description:
+
+ This function is the dialog procedure for the value-add software selection
+ wizard page. If the user selects any software on this page, the software
+ will be automatically installed when the user presses "Next".
+
+Arguments:
+
+ hwndDlg - Supplies a handle to the dialog box window
+
+ uMsg - Supplies the message
+
+ wParam - Supplies the first message parameter
+
+ lParam - Supplies the second message parameter
+
+Return Value:
+
+ This dialog procedure always returns zero.
+
+--*/
+
+{
+ LPVALUEADDWIZDATA pdata;
+ LPNMHDR lpnm;
+ HKEY hKey;
+
+ UNREFERENCED_PARAMETER( wParam );
+
+ //
+ // Retrieve the shared user data from GWL_USERDATA
+ //
+ pdata = (LPVALUEADDWIZDATA) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch(uMsg) {
+
+ case WM_INITDIALOG :
+ //
+ // Get the PROPSHEETPAGE lParam value and load it into GWL_USERDATA
+ //
+ pdata = (LPVALUEADDWIZDATA) ((LPPROPSHEETPAGE)lParam)->lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)pdata);
+ break;
+
+ case WM_NOTIFY :
+
+ lpnm = (LPNMHDR)lParam;
+
+ switch(lpnm->code) {
+
+ case PSN_SETACTIVE :
+ //
+ // Enable the Next and Back buttons
+ //
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_NEXT);
+ break;
+
+ case PSN_WIZNEXT :
+ //
+ // Install any applications the user selected.
+ //
+ if(IsDlgButtonChecked(hwndDlg, IDC_CHECK1) && !pdata->AppInstallAttempted) {
+
+ BOOL MediaPresent = FALSE;
+ WCHAR PathToSetupExe[MAX_PATH];
+ PWSTR LastChar;
+
+ //
+ // If we need to prompt the user for media, do so now.
+ //
+ if(*(pdata->MediaDiskName)) {
+
+ WCHAR TempString[64];
+ size_t PathLength;
+
+ if(!LoadString(g_hInstance,
+ IDS_MEDIA_PROMPT_TITLE,
+ TempString,
+ sizeof(TempString) / sizeof(WCHAR))) {
+
+ *TempString = TEXT('\0');
+ }
+
+ //
+ // Append subdirectory where toastapp's setup.exe
+ // is located, so we can prompt user for media.
+ //
+ if (FAILED(StringCchLength(pdata->MediaRootDirectory,
+ MAX_PATH,
+ &PathLength))) {
+ break;
+ }
+
+ LastChar = pdata->MediaRootDirectory + PathLength;
+
+ if(FAILED(StringCchCopy(LastChar,
+ MAX_PATH - PathLength,
+ TOASTAPP_SETUP_SUBDIR))) {
+ break;
+ }
+
+ //
+ // (Note, we skip the first character in
+ // SetupExeName for our "FileSought" argument
+ // below, because we don't want to include the
+ // first character, which is a path separator.)
+ //
+ if(DPROMPT_SUCCESS == SetupPromptForDisk(
+ GetParent(hwndDlg),
+ TempString,
+ pdata->MediaDiskName,
+ pdata->MediaRootDirectory,
+ SetupExeName+1,
+ pdata->MediaTagFile,
+ IDF_CHECKFIRST | IDF_NOBEEP,
+ PathToSetupExe,
+ MAX_PATH,
+ (PDWORD)&PathLength))
+ {
+ MediaPresent = TRUE;
+ }
+
+ //
+ // Strip the ToastApp subdir off media root path
+ //
+ *LastChar = L'\0';
+
+ if(MediaPresent) {
+ //
+ // SetupPromptForDisk gives us the directory
+ // where our setup program is located--now we
+ // need to append the setup program onto the
+ // end of that path.
+ //
+ PathLength--; // Don't include terminating null
+
+ if((PathToSetupExe[PathLength-1] != L'\\') &&
+ (PathToSetupExe[PathLength-1] != L'/')) {
+ //
+ // We need the path separator char...
+ //
+ if(FAILED(StringCchCopy(PathToSetupExe+PathLength,
+ MAX_PATH - PathLength,
+ SetupExeName))) {
+ break;
+ }
+
+ } else {
+ //
+ // We don't need the path separator char...
+ //
+ if(FAILED(StringCchCopy(PathToSetupExe+PathLength,
+ MAX_PATH - PathLength,
+ SetupExeName+1))) {
+ break;
+ }
+
+ }
+ }
+
+ } else {
+
+ //
+ // Assume media is already present (i.e., because
+ // we're in our auto-launch setup program running
+ // off the media.
+ //
+ MediaPresent = TRUE;
+
+ //
+ // Construct the fully-qualified path to the setup
+ // executable.
+ //
+ if(FAILED(StringCchCopy(PathToSetupExe,
+ MAX_PATH,
+ pdata->MediaRootDirectory))) {
+ break;
+ }
+
+ if(FAILED(StringCchCat(PathToSetupExe,
+ MAX_PATH,
+ TOASTAPP_SETUP_PATH))) {
+ break;
+ }
+
+ }
+
+ if(MediaPresent) {
+ //
+ // We're attempting app install. Success or
+ // failure, we don't want to try again.
+ //
+ pdata->AppInstallAttempted = TRUE;
+
+ if(!InstallToastApp(GetParent(hwndDlg), PathToSetupExe)) {
+ //
+ // We failed to install the toast app. Un-check
+ // the checkbox before we disable it.
+ //
+ CheckDlgButton(hwndDlg, IDC_CHECK1, BST_UNCHECKED);
+ }
+
+ EnableWindow(GetDlgItem(hwndDlg, IDC_CHECK1), FALSE);
+ }
+ }
+
+ break;
+
+ case PSN_KILLACTIVE :
+ //
+ // If we get to this point, we know that our wizard page
+ // has been displayed. We can now set the "User Prompted"
+ // registry flag, certain that the user has been given the
+ // opportunity to select the value-added software they wish
+ // to install.
+ //
+ if(ERROR_SUCCESS == RegCreateKeyEx(
+ HKEY_LOCAL_MACHINE,
+ TEXT("SOFTWARE\\Microsoft\\Toaster"),
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WRITE,
+ NULL,
+ &hKey,
+ NULL)) {
+
+ DWORD UserPrompted = 1;
+
+ RegSetValueEx(hKey,
+ TEXT("User Prompted"),
+ 0,
+ REG_DWORD,
+ (PBYTE)&UserPrompted,
+ sizeof(UserPrompted)
+ );
+
+ RegCloseKey(hKey);
+ }
+
+ break;
+
+ case PSN_WIZBACK :
+ //Handle a Back button click, if necessary
+ break;
+
+ case PSN_RESET :
+ //Handle a Cancel button click, if necessary
+ break;
+
+ default :
+ break;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+_Success_(return == TRUE)
+BOOL
+GetMediaRootDirectory(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVINFO_DATA DeviceInfoData,
+ _Out_ LPWSTR *MediaRootDirectory,
+ _Outptr_result_maybenull_ LPWSTR *MediaDiskName,
+ _Outptr_result_maybenull_ LPWSTR *MediaTagFile
+ )
+
+/*++
+
+Routine Description:
+
+ This function retrieves the root of the installation media for the INF
+ selected in the specified device information element.
+
+ There are two possibilities here:
+
+ 1. INF is on source media. If so, then just use that path.
+
+ 2. INF is already in %windir%\Inf. This is less likely, because we
+ should've previously prompted the user to install software at the
+ time the INF was installed. However, perhaps someone called
+ SetupCopyOEMInf to install the INF without prompting the user for
+ value-add software selection. Another way you could get into this
+ state is if the user previously elected to install the application,
+ then subsequently uninstalled it via "Add/Remove Programs". The MSI
+ package is configured to delete the UserPrompted value from the
+ registry during uninstall, so if a new toaster is subsequently
+ inserted, the user will be prompted once again.
+
+ When the INF is in %windir%\Inf, we need to retrieve the original
+ source location from which the INF was installed. Plug&Play stores
+ this information for 3rd-party INF files, but it is not directly
+ accessible. Fortunately, there is an INF DIRID that corresponds to
+ this path, so we retrieve the value of that DIRID from the INF in
+ order to ascertain the media root directory.
+
+Arguments:
+
+ DeviceInfoSet - Supplies a handle to the device information set containing
+ the element for which an INF driver node is currently selected.
+
+ DeviceInfoData - Supplies the address of a device information element for
+ which an INF driver node is currently selected.
+
+ MediaRootDirectory - Supplies the address of a string pointer that, upon
+ successful return, will be set to point to a newly-allocated string
+ containing the root directory of the setup media. The caller must free
+ this buffer via GlobalFree.
+
+ This pointer will be set to NULL upon error.
+
+ MediaDiskName - Supplies the address of a string pointer that, upon
+ successful return will be set to either:
+
+ 1. A newly-allocated string containing the disk name to be used
+ when prompting for the setup media (when INF is in %windir%\Inf)
+ 2. NULL (when INF isn't in %windir%\Inf it is presumed to be on
+ source media, hence no prompting is necessary)
+
+ This pointer will be set to NULL upon error.
+
+ MediaTagFile - Supplies the address of a string pointer that, upon
+ successful return will be set to either:
+
+ 1. A newly-allocated string containing the disk tagfile to be used
+ when prompting for the setup media (when INF is in %windir%\Inf)
+ 2. NULL (when INF isn't in %windir%\Inf it is presumed to be on
+ source media, hence no prompting is necessary)
+
+ This pointer will be set to NULL upon error.
+
+Return Value:
+
+ If this function succeeds, the return value is non-zero (TRUE).
+
+ If this function fails, the return value is FALSE.
+
+--*/
+
+{
+ SP_DRVINFO_DATA DriverInfoData;
+ PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData = NULL;
+ LPWSTR FileNamePart;
+ WCHAR InfDirPath[MAX_PATH];
+ BOOL b = FALSE;
+ HINF hInf = INVALID_HANDLE_VALUE;
+ INFCONTEXT InfContext;
+ DWORD PathLength;
+
+ *MediaRootDirectory = NULL;
+ *MediaDiskName = NULL;
+ *MediaTagFile = NULL;
+
+ //
+ // First, retrieve the full path of the INF being used to install this
+ // device.
+ //
+ DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
+
+ if(!SetupDiGetSelectedDriver(DeviceInfoSet, DeviceInfoData, &DriverInfoData)) {
+ //
+ // This shouldn't fail, but if it does, just bail.
+ //
+ goto clean0;
+ }
+
+ //
+ // Retrieve the driver info details. We don't care about the id list at
+ // the end, so we can just allocate a buffer for the fixed-size part...
+ //
+ DriverInfoDetailData = GlobalAlloc(0, sizeof(SP_DRVINFO_DETAIL_DATA));
+ if(!DriverInfoDetailData) {
+ goto clean0;
+ }
+ DriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
+
+ if(!SetupDiGetDriverInfoDetail(DeviceInfoSet,
+ DeviceInfoData,
+ &DriverInfoData,
+ DriverInfoDetailData,
+ sizeof(SP_DRVINFO_DETAIL_DATA),
+ NULL)
+ && (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
+ {
+ //
+ // Again, this should never fail, but if it does we're outta here.
+ //
+ goto clean0;
+ }
+
+ *MediaRootDirectory = GlobalAlloc(0, MAX_PATH * sizeof(WCHAR));
+ if(!*MediaRootDirectory) {
+ goto clean0;
+ }
+
+ //
+ // Strip the INF name off of the path. (Resultant path will always end
+ // with a path separator char ('\\').)
+ //
+ PathLength = GetFullPathName(DriverInfoDetailData->InfFileName,
+ MAX_PATH,
+ *MediaRootDirectory,
+ &FileNamePart
+ );
+
+ if(!PathLength || (PathLength >= MAX_PATH)) {
+ goto clean0;
+ }
+
+ *FileNamePart = L'\0';
+
+ //
+ // Check to see this INF is already in %windir%\Inf.
+ //
+ PathLength = GetSystemWindowsDirectory(InfDirPath, MAX_PATH);
+
+ if(!PathLength || (PathLength >= MAX_PATH)) {
+ goto clean0;
+ }
+
+ //
+ // Append INF directory to path (making sure we don't end up with two path
+ // separator chars).
+ //
+ if((InfDirPath[PathLength-1] != L'\\') && (InfDirPath[PathLength-1] != L'/')) {
+ if(FAILED(StringCchCopy(&(InfDirPath[PathLength]),
+ MAX_PATH - PathLength,
+ L"\\Inf\\"))) {
+ goto clean0;
+ }
+ } else {
+
+ if(FAILED(StringCchCopy(&(InfDirPath[PathLength]),
+ MAX_PATH - PathLength,
+ L"Inf\\"))) {
+ goto clean0;
+ }
+ }
+
+ if(lstrcmpi(*MediaRootDirectory, InfDirPath)) {
+ //
+ // The INF isn't in %windir%\Inf, so assume its location is the root of
+ // the installation media. (We don't bother to retrieve the disk name
+ // or tagfile name in this case.)
+ //
+ b = TRUE;
+ goto clean0;
+ }
+
+ //
+ // Since the INF is already in %windir%\Inf, we need to find out where it
+ // originally came from. There is no direct way to ascertain an INF's
+ // path of origin, but we can indirectly determine it by retrieving a field
+ // from our INF that uses a string substitution of %1% (DIRID_SRCPATH).
+ //
+ hInf = SetupOpenInfFile(DriverInfoDetailData->InfFileName,
+ NULL,
+ INF_STYLE_WIN4,
+ NULL
+ );
+
+ if(hInf == INVALID_HANDLE_VALUE) {
+ goto clean0;
+ }
+
+ //
+ // Contained within our INF should be a [ToastCoInfo] section with the
+ // following entry:
+ //
+ // OriginalInfSourcePath = %1%
+ //
+ // If we retrieve the value (i.e., field 1) of this line, we'll get the
+ // full path where the INF originally came from.
+ //
+ if(!SetupFindFirstLine(hInf, L"ToastCoInfo", L"OriginalInfSourcePath", &InfContext)) {
+ goto clean0;
+ }
+
+ if(!SetupGetStringField(&InfContext, 1, *MediaRootDirectory, MAX_PATH, &PathLength) ||
+ (PathLength <= 1)) {
+ goto clean0;
+ }
+
+ //
+ // PathLength we get back includes the terminating null character. Subtract
+ // one to get actual length of string.
+ //
+ PathLength--;
+
+ //
+ // Ensure the path we retrieved has a path separator character at the end.
+ //
+ if(((*MediaRootDirectory)[PathLength-1] != L'\\') &&
+ ((*MediaRootDirectory)[PathLength-1] != L'/'))
+ {
+ if(FAILED(StringCchCopy(*MediaRootDirectory+PathLength,
+ MAX_PATH - PathLength,
+ L"\\"))) {
+ goto clean0;
+ }
+ }
+
+ //
+ // Now retrieve the disk name and tagfile for our setup media.
+ //
+ *MediaDiskName = GlobalAlloc(0, LINE_LEN * sizeof(WCHAR));
+ *MediaTagFile = GlobalAlloc(0, MAX_PATH * sizeof(WCHAR));
+
+ if(!(*MediaDiskName && *MediaTagFile)) {
+ goto clean0;
+ }
+
+ if(!SetupGetSourceInfo(hInf,
+ TOASTER_MEDIA_SOURCE_ID,
+ SRCINFO_DESCRIPTION,
+ *MediaDiskName,
+ LINE_LEN,
+ NULL)) {
+ goto clean0;
+ }
+
+ if(!SetupGetSourceInfo(hInf,
+ TOASTER_MEDIA_SOURCE_ID,
+ SRCINFO_TAGFILE,
+ *MediaTagFile,
+ MAX_PATH,
+ NULL)) {
+ goto clean0;
+ }
+
+ b = TRUE;
+
+clean0:
+
+ if(hInf != INVALID_HANDLE_VALUE) {
+ SetupCloseInfFile(hInf);
+ }
+
+ if(DriverInfoDetailData) {
+ GlobalFree(DriverInfoDetailData);
+ }
+
+ if(!b) {
+ if(*MediaRootDirectory) {
+ GlobalFree(*MediaRootDirectory);
+ *MediaRootDirectory = NULL;
+ }
+ if(*MediaDiskName) {
+ GlobalFree(*MediaDiskName);
+ *MediaDiskName = NULL;
+ }
+ if(*MediaTagFile) {
+ GlobalFree(*MediaTagFile);
+ *MediaTagFile = NULL;
+ }
+ }
+
+ return b;
+}
+
+
+HPROPSHEETPAGE
+GetValueAddSoftwareWizPage(
+ _In_ LPCWSTR MediaRootDirectory,
+ _In_opt_ LPCWSTR MediaDiskName,
+ _In_opt_ LPCWSTR MediaTagFile
+ )
+
+/*++
+
+Routine Description:
+
+ This function returns a newly-created property sheet page handle that may
+ be used in a wizard to allow user-selection of value-added software.
+
+ This wizard page is used by both the toaster co-installer (as a finish-
+ install wizard page), as well as by the toastva installation application.
+
+Arguments:
+
+ MediaRootDirectory - Supplies the fully-qualified path to the root of the
+ installation media.
+
+ MediaDiskName - Optionally, supplies the name of the disk to be used when
+ prompting the user for source media. If this parameter is not
+ supplied, the media is assumed to already be present, and no prompting
+ occurs
+
+ MediaTagFile - Optionally, supplies the tagfile for the disk to be used
+ when prompting the user for source media. If MediaDiskName is not
+ specified, this parameter is ignored.
+
+Return Value:
+
+ If this function succeeds, the return value is a newly-created property
+ sheet page handle.
+
+ If this function fails, the return value is NULL.
+
+--*/
+
+{
+ HPROPSHEETPAGE hpsp;
+ LPVALUEADDWIZDATA ValueAddWizData; //data for the value-add sw chooser page
+ PROPSHEETPAGE page;
+
+ ValueAddWizData = GlobalAlloc(0, sizeof(VALUEADDWIZDATA));
+
+ if(ValueAddWizData) {
+ ZeroMemory(ValueAddWizData, sizeof(VALUEADDWIZDATA));
+ } else {
+ return NULL;
+ }
+
+ if(FAILED(StringCchCopy(ValueAddWizData->MediaRootDirectory,
+ MAX_PATH,
+ MediaRootDirectory))) {
+ return NULL;
+ }
+
+ if(MediaDiskName && MediaTagFile) {
+ //
+ // The caller wants us to prompt user for media (e.g., installation
+ // occurring from %windir%\Inf\OEM<n>.INF, and we want to ensure that
+ // our CD is in the drive before launching setup.exe from it).
+ //
+ if(FAILED(StringCchCopy(ValueAddWizData->MediaDiskName,
+ LINE_LEN,
+ MediaDiskName))) {
+ return NULL;
+ }
+
+ if(FAILED(StringCchCopy(ValueAddWizData->MediaTagFile,
+ MAX_PATH,
+ MediaTagFile))) {
+ return NULL;
+ }
+ }
+
+ ZeroMemory(&page, sizeof(PROPSHEETPAGE));
+
+ //
+ // Create the sample Wizard Page
+ //
+ page.dwSize = sizeof(PROPSHEETPAGE);
+ page.dwFlags = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE|PSP_USETITLE|PSP_USECALLBACK;
+ page.hInstance = g_hInstance;
+ page.pszHeaderTitle = MAKEINTRESOURCE(IDS_TITLE);
+ page.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUBTITLE);
+ page.pszTemplate = MAKEINTRESOURCE(IDD_SAMPLE_INSTALLAPP);
+ page.pfnDlgProc = ValueAddDlgProc;
+ page.lParam = (LPARAM)ValueAddWizData;
+ page.pfnCallback = (LPFNPSPCALLBACKW) ValueAddPropSheetPageProc;
+
+ hpsp = CreatePropertySheetPage(&page);
+
+ if(!hpsp) {
+ GlobalFree(ValueAddWizData);
+ }
+
+ return hpsp;
+}
+
+
+VOID
+SetDeviceFriendlyName(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVINFO_DATA DeviceInfoData
+ )
+
+/*++
+
+Routine Description:
+
+ This function retrieves the (localized) string format (suitable for use
+ with FormatMessage) to be used in generating the device's friendly name,
+ then constructs the name using that format in concert with the device's UI
+ number.
+
+Arguments:
+
+ DeviceInfoSet - Supplies a handle to the device information set containing
+ the element for which an INF driver node is currently selected.
+
+ DeviceInfoData - Supplies the address of a device information element for
+ which an INF driver node is currently selected.
+
+Return Value:
+
+ none
+
+--*/
+
+{
+ SP_DRVINFO_DATA DriverInfoData;
+ SP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
+ HINF hInf;
+ WCHAR InfSectionWithExt[255];
+ WCHAR FormatString[LINE_LEN];
+ INFCONTEXT InfContext;
+ DWORD UINumber;
+ PVOID FriendlyNameBuffer;
+ DWORD FriendlyNameBufferSize;
+
+ //
+ // First, retrieve the format string from the driver's [DDInstall] section.
+ //
+ DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
+ if(!SetupDiGetSelectedDriver(DeviceInfoSet,
+ DeviceInfoData,
+ &DriverInfoData)) {
+ //
+ // NULL driver install
+ //
+ goto clean0;
+ }
+
+ DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
+ if(!SetupDiGetDriverInfoDetail(DeviceInfoSet,
+ DeviceInfoData,
+ &DriverInfoData,
+ &DriverInfoDetailData,
+ sizeof(DriverInfoDetailData),
+ NULL) &&
+ (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
+ {
+ //
+ // Unable to retrieve detail info about selected driver node
+ //
+ goto clean0;
+ }
+
+ hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName,
+ NULL,
+ INF_STYLE_WIN4,
+ NULL
+ );
+
+ if(hInf == INVALID_HANDLE_VALUE) {
+ //
+ // Couldn't open the INF
+ //
+ goto clean0;
+ }
+
+ //
+ // Figure out actual (potentially decorated) DDInstall section being used
+ // for this install.
+ //
+ *FormatString = L'\0'; // default to empty string in case error occurs.
+
+ if(SetupDiGetActualSectionToInstall(hInf,
+ DriverInfoDetailData.SectionName,
+ InfSectionWithExt,
+ sizeof(InfSectionWithExt) / sizeof(WCHAR),
+ NULL,
+ NULL)) {
+
+ if(SetupFindFirstLine(hInf,
+ InfSectionWithExt,
+ L"FriendlyNameFormat",
+ &InfContext)) {
+
+ if(!SetupGetStringField(&InfContext,
+ 1,
+ FormatString,
+ sizeof(FormatString) / sizeof(WCHAR),
+ NULL)) {
+ //
+ // Failed to retrieve format string into our buffer. Make sure
+ // our buffer still contains an empty string.
+ //
+ *FormatString = L'\0';
+ }
+ }
+ }
+
+ SetupCloseInfFile(hInf);
+
+ if(!(*FormatString)) {
+ goto clean0;
+ }
+
+ //
+ // Now retrieve the device's UI number, which is actually the serial number
+ // used by the bus driver.
+ //
+ if(SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+ DeviceInfoData,
+ SPDRP_UI_NUMBER,
+ NULL,
+ (PBYTE)&UINumber,
+ sizeof(UINumber),
+ NULL)) {
+
+ FriendlyNameBufferSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
+ | FORMAT_MESSAGE_FROM_STRING
+ | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ FormatString,
+ 0,
+ 0,
+ (LPWSTR)&FriendlyNameBuffer,
+ 0,
+ (va_list *)&UINumber
+ );
+
+ if(FriendlyNameBufferSize) {
+
+ SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
+ DeviceInfoData,
+ SPDRP_FRIENDLYNAME,
+ (PBYTE)FriendlyNameBuffer,
+ (FriendlyNameBufferSize + 1) * sizeof(WCHAR)
+ );
+
+ LocalFree(FriendlyNameBuffer);
+ }
+ }
+
+clean0:
+ ; // nothing to do
+}
+
diff --git a/general/toaster/toastpkg/toastco/toastco.h b/general/toaster/toastpkg/toastco/toastco.h
new file mode 100644
index 00000000..ab1d4f9b
--- /dev/null
+++ b/general/toaster/toastpkg/toastco/toastco.h
@@ -0,0 +1,33 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ toastco.h
+
+Abstract:
+
+ Header files and resource IDs used by the Toaster sample co-installer.
+
+--*/
+
+
+#include <windows.h>
+#include <setupapi.h>
+
+
+#define IDD_SAMPLE_INSTALLAPP 900
+#define IDC_CHECK1 1000
+#define IDC_CHECK2 1001
+#define IDC_CHECK3 1002
+#define IDC_STATIC -1
+#define IDS_TITLE 1
+#define IDS_SUBTITLE 2
+#define IDS_MEDIA_PROMPT_TITLE 3
+
diff --git a/general/toaster/toastpkg/toastco/toastco.rc b/general/toaster/toastpkg/toastco/toastco.rc
new file mode 100644
index 00000000..384181ef
--- /dev/null
+++ b/general/toaster/toastpkg/toastco/toastco.rc
@@ -0,0 +1,85 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ toastco.rc
+
+Abstract:
+
+ Resources used by the Toaster sample co-installer
+
+--*/
+
+#include "toastco.h"
+#include <windows.h>
+
+//
+// Version resources
+//
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,0,0,0
+ PRODUCTVERSION 2,0,0,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Microsoft Corporation\0"
+ VALUE "FileDescription", "Toaster CoInstaller Sample\0"
+ VALUE "FileVersion", "2.00.0000.0\0"
+ VALUE "InternalName", "TOSTRCO2.DLL\0"
+ VALUE "LegalCopyright", "� Microsoft Corporation. All rights reserved.\0"
+ VALUE "OriginalFilename", "TOSTRCO2.DLL\0"
+ VALUE "ProductName", "Toaster DDK Sample\0"
+ VALUE "ProductVersion", "2.0.0000.0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+//
+// Dialog resources
+//
+IDD_SAMPLE_INSTALLAPP DIALOG DISCARDABLE 0, 0, 317, 143
+STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Please select the applications that you would like to install:",
+ IDC_STATIC,11,0,304,8
+ CONTROL "Toaster Device Interface Watcher",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,21,20,296,10
+ CONTROL "Toaster Diagnostic Utility",IDC_CHECK2,"Button",BS_AUTOCHECKBOX |
+ WS_DISABLED | WS_TABSTOP,21,34,296,10
+ CONTROL "Toast-Made-Easy Recipe Program",IDC_CHECK3,"Button",BS_AUTOCHECKBOX |
+ WS_DISABLED | WS_TABSTOP,21,48,296,10
+END
+
+//
+// String Table resources
+//
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_TITLE "Choose Additional Applications"
+ IDS_SUBTITLE "These applications make it quick and easy to make great toast!"
+ IDS_MEDIA_PROMPT_TITLE "Toaster"
+END
+
diff --git a/general/toaster/toastpkg/toastco/tostrco2.def b/general/toaster/toastpkg/toastco/tostrco2.def
new file mode 100644
index 00000000..5ee4e35b
--- /dev/null
+++ b/general/toaster/toastpkg/toastco/tostrco2.def
@@ -0,0 +1,24 @@
+;/*++
+;
+;Copyright (c) Microsoft Corporation. All rights reserved.
+;
+; THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+; KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+; IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+; PURPOSE.
+;
+;Module Name:
+;
+; tostrco2.def
+;
+;Abstract:
+;
+; Specifies exports for the Toaster Package sample co-installer (version 2)
+;
+;--*/
+
+LIBRARY tostrco2
+
+EXPORTS
+ ToasterCoInstaller
+ GetValueAddSoftwareWizPage
diff --git a/general/toaster/toastpkg/toastco/tostrco2.vcxproj b/general/toaster/toastpkg/toastco/tostrco2.vcxproj
new file mode 100644
index 00000000..ee1a266f
--- /dev/null
+++ b/general/toaster/toastpkg/toastco/tostrco2.vcxproj
@@ -0,0 +1,243 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{F4010EA2-CDEF-4E68-AF56-C0240162D712}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>tostrco2</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>tostrco2</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>tostrco2</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>tostrco2</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Link>
+ <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
+ <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Link>
+ <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
+ <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Link>
+ <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
+ <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Link>
+ <EntryPointSymbol Condition="'$(Platform)'=='win32'">_DllMainCRTStartup@12</EntryPointSymbol>
+ <EntryPointSymbol Condition="'$(Platform)'!='win32'">_DllMainCRTStartup</EntryPointSymbol>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib;kernel32.lib;comctl32.lib;advapi32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib;kernel32.lib;comctl32.lib;advapi32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib;kernel32.lib;comctl32.lib;advapi32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib;kernel32.lib;comctl32.lib;advapi32.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Link>
+ <ModuleDefinitionFile>tostrco2.def</ModuleDefinitionFile>
+ </Link>
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Link>
+ <ModuleDefinitionFile>tostrco2.def</ModuleDefinitionFile>
+ </Link>
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Link>
+ <ModuleDefinitionFile>tostrco2.def</ModuleDefinitionFile>
+ </Link>
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Link>
+ <ModuleDefinitionFile>tostrco2.def</ModuleDefinitionFile>
+ </Link>
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="precompsrc.c">
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Create</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="toastco.c">
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ResourceCompile Include="toastco.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastco/tostrco2.vcxproj.Filters b/general/toaster/toastpkg/toastco/tostrco2.vcxproj.Filters
new file mode 100644
index 00000000..5639c710
--- /dev/null
+++ b/general/toaster/toastpkg/toastco/tostrco2.vcxproj.Filters
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{FF79EB36-D2F2-497B-9B3B-1F5D4BA911D4}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{A4BFE1CB-F5FD-4F98-8EA6-6B0F543535C6}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{F4E6AFB3-5EF2-4D35-92BF-D0DAD16E87B5}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="precompsrc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="toastco.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <None Include="tostrco2.def">
+ <Filter>Source Files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="toastco.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastpkg.sln b/general/toaster/toastpkg/toastpkg.sln
new file mode 100644
index 00000000..13fee6ef
--- /dev/null
+++ b/general/toaster/toastpkg/toastpkg.sln
@@ -0,0 +1,62 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0
+MinimumVisualStudioVersion = 12.0
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Toastapp", "Toastapp", "{BFAE4A6A-CD41-4052-AC38-EAC4DB8494DF}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Toastco", "Toastco", "{4C142C9D-56A8-44C0-84F1-D4ABBFA3E9F8}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Toastva", "Toastva", "{47FE1DB3-FA82-4F24-96B1-C6798AA08C61}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toastapp", "toastapp\toastapp.vcxproj", "{1C818755-28B2-4C84-8623-FF84F3326B64}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tostrco2", "toastco\tostrco2.vcxproj", "{84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toastva", "toastva\toastva.vcxproj", "{7A49D840-4E82-477B-8105-CF546E4FD034}"
+ ProjectSection(ProjectDependencies) = postProject
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22} = {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1C818755-28B2-4C84-8623-FF84F3326B64}.Debug|Win32.ActiveCfg = Debug|Win32
+ {1C818755-28B2-4C84-8623-FF84F3326B64}.Debug|Win32.Build.0 = Debug|Win32
+ {1C818755-28B2-4C84-8623-FF84F3326B64}.Release|Win32.ActiveCfg = Release|Win32
+ {1C818755-28B2-4C84-8623-FF84F3326B64}.Release|Win32.Build.0 = Release|Win32
+ {1C818755-28B2-4C84-8623-FF84F3326B64}.Debug|x64.ActiveCfg = Debug|x64
+ {1C818755-28B2-4C84-8623-FF84F3326B64}.Debug|x64.Build.0 = Debug|x64
+ {1C818755-28B2-4C84-8623-FF84F3326B64}.Release|x64.ActiveCfg = Release|x64
+ {1C818755-28B2-4C84-8623-FF84F3326B64}.Release|x64.Build.0 = Release|x64
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}.Debug|Win32.ActiveCfg = Debug|Win32
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}.Debug|Win32.Build.0 = Debug|Win32
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}.Release|Win32.ActiveCfg = Release|Win32
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}.Release|Win32.Build.0 = Release|Win32
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}.Debug|x64.ActiveCfg = Debug|x64
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}.Debug|x64.Build.0 = Debug|x64
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}.Release|x64.ActiveCfg = Release|x64
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22}.Release|x64.Build.0 = Release|x64
+ {7A49D840-4E82-477B-8105-CF546E4FD034}.Debug|Win32.ActiveCfg = Debug|Win32
+ {7A49D840-4E82-477B-8105-CF546E4FD034}.Debug|Win32.Build.0 = Debug|Win32
+ {7A49D840-4E82-477B-8105-CF546E4FD034}.Release|Win32.ActiveCfg = Release|Win32
+ {7A49D840-4E82-477B-8105-CF546E4FD034}.Release|Win32.Build.0 = Release|Win32
+ {7A49D840-4E82-477B-8105-CF546E4FD034}.Debug|x64.ActiveCfg = Debug|x64
+ {7A49D840-4E82-477B-8105-CF546E4FD034}.Debug|x64.Build.0 = Debug|x64
+ {7A49D840-4E82-477B-8105-CF546E4FD034}.Release|x64.ActiveCfg = Release|x64
+ {7A49D840-4E82-477B-8105-CF546E4FD034}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {1C818755-28B2-4C84-8623-FF84F3326B64} = {BFAE4A6A-CD41-4052-AC38-EAC4DB8494DF}
+ {84F11D30-54EE-479A-8F8A-7FBFA8E6BE22} = {4C142C9D-56A8-44C0-84F1-D4ABBFA3E9F8}
+ {7A49D840-4E82-477B-8105-CF546E4FD034} = {47FE1DB3-FA82-4F24-96B1-C6798AA08C61}
+ EndGlobalSection
+EndGlobal
diff --git a/general/toaster/toastpkg/toastva/header.bmp b/general/toaster/toastpkg/toastva/header.bmp
new file mode 100644
index 00000000..49a4cb45
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/header.bmp
Binary files differ
diff --git a/general/toaster/toastpkg/toastva/precomp.h b/general/toaster/toastpkg/toastva/precomp.h
new file mode 100644
index 00000000..de91c9b6
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/precomp.h
@@ -0,0 +1,21 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ precomp.h
+
+Abstract:
+
+ Single container to facilitate use of precompiled headers.
+
+--*/
+
+#include "toastva.h"
+#include "strsafe.h"
diff --git a/general/toaster/toastpkg/toastva/precompsrc.c b/general/toaster/toastpkg/toastva/precompsrc.c
new file mode 100644
index 00000000..5944cf51
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/precompsrc.c
@@ -0,0 +1 @@
+#include "precomp.h" \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastva/resource.h b/general/toaster/toastpkg/toastva/resource.h
new file mode 100644
index 00000000..f5ab4bb0
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/resource.h
@@ -0,0 +1,61 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ resource.h
+
+Abstract:
+
+ Resource IDs used by the TOASTVA sample.
+
+--*/
+
+#define IDS_TITLE1 1
+#define IDS_SUBTITLE1 2
+#define IDS_TITLE2 3
+#define IDS_SUBTITLE2 4
+#define IDS_CAPTION 5
+#define IDS_PROMPT_FOR_HW 6
+#define IDB_BANNER 102
+#define IDB_WATERMARK 103
+#define IDI_ICON1 104
+#define IDD_INTRO 107
+#define IDD_INTERIOR1 108
+#define IDD_INTERIOR2 109
+#define IDD_END 110
+#define IDC_TITLE 1000
+#define IDC_INTRO_TEXT 1001
+#define IDC_RADIO1 1002
+#define IDC_RADIO2 1003
+#define IDC_RADIO3 1004
+#define IDC_EDIT2 1006
+#define IDC_EDIT3 1007
+#define IDC_EDIT4 1008
+#define IDC_CHECK1 1010
+#define IDC_GROUP1 1011
+#define IDC_CHECK3 1013
+#define IDC_CHECK4 1014
+#define IDC_CHECK5 1015
+#define IDC_ANIMATE1 1016
+#define IDC_FINISH_TEXT 1017
+#define IDC_STATIC -1
+#define IDA_SEARCHING 300
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 105
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1018
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
+
diff --git a/general/toaster/toastpkg/toastva/search.avi b/general/toaster/toastpkg/toastva/search.avi
new file mode 100644
index 00000000..24850baa
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/search.avi
Binary files differ
diff --git a/general/toaster/toastpkg/toastva/toastapp.ico b/general/toaster/toastpkg/toastva/toastapp.ico
new file mode 100644
index 00000000..55ab969e
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/toastapp.ico
Binary files differ
diff --git a/general/toaster/toastpkg/toastva/toastva.c b/general/toaster/toastpkg/toastva/toastva.c
new file mode 100644
index 00000000..be842667
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/toastva.c
@@ -0,0 +1,209 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ toastva.c
+
+Abstract:
+
+ The TOASTVA application illustrates installation techniques that can be
+ used to seamlessly integrate PnP device installation with installation of
+ value-added software, regardless of whether the software installation
+ preceeded the hardware installation, or vice versa.
+
+--*/
+
+#include "precomp.h"
+#pragma hdrstop
+
+
+//
+// Constants
+//
+#if defined(_IA64_)
+ #define TOASTVA_PLATFORM_SUBDIRECTORY L"ia64"
+#elif defined(_X86_)
+ #define TOASTVA_PLATFORM_SUBDIRECTORY L"i386"
+#elif defined(_AMD64_)
+ #define TOASTVA_PLATFORM_SUBDIRECTORY L"amd64"
+#elif defined(_ARM_)
+ #define TOASTVA_PLATFORM_SUBDIRECTORY L"arm"
+#elif defined(_ARM64_)
+ #define TOASTVA_PLATFORM_SUBDIRECTORY L"arm64"
+#else
+#error Unsupported platform
+#endif
+
+#define TOASTVA_PLATFORM_SUBDIRECTORY_SIZE (sizeof(TOASTVA_PLATFORM_SUBDIRECTORY) / sizeof(WCHAR))
+
+//
+// Globals
+//
+HINSTANCE g_hInstance;
+
+
+//
+// Implementation
+//
+
+INT
+WINAPI
+WinMain(
+ _In_ HINSTANCE hInstance,
+ _In_opt_ HINSTANCE hPrevInstance,
+ _In_ LPSTR lpCmdLine,
+ _In_ int nShowCmd
+ )
+{
+ LPWSTR *ArgList;
+ INT NumArgs;
+ WCHAR MediaRootDirectory[MAX_PATH];
+ LPWSTR FileNamePart;
+ DWORD DirPathLength;
+
+ g_hInstance = hInstance;
+
+ UNREFERENCED_PARAMETER(hPrevInstance);
+ UNREFERENCED_PARAMETER(lpCmdLine);
+ UNREFERENCED_PARAMETER(nShowCmd);
+
+ //
+ // Windows 2000 doesn't suppress auto-run applications when media (e.g.,
+ // a CD) is inserted while a "Found New Hardware" popup is onscreen. This
+ // means that, by default, inserting a CD in order to supply PnP with the
+ // necessary INF and driver files will result in the autorun app launching,
+ // and obscuring the wizard, causing user confusion, etc.
+ //
+ // To avoid this, we retrieve an entrypoint to a Windows 2000 (and later)
+ // Configuration Manager (CM) API that allows us to detect when a device
+ // installation is in-progress, and suppress our own application from
+ // starting.
+ //
+ if(IsDeviceInstallInProgress()) {
+ //
+ // We don't want to startup right now. Don't worry--the value-added
+ // software part of the device installation will be invoked (if
+ // necessary) by our device co-installer during finish-install
+ // processing.
+ //
+ return 0;
+ }
+
+ //
+ // Retrieve the full directory path from which our setup program was
+ // invoked.
+ //
+ ArgList = CommandLineToArgvW(GetCommandLine(), &NumArgs);
+
+ if(ArgList && (NumArgs >= 1)) {
+
+ DirPathLength = GetFullPathName(ArgList[0],
+ MAX_PATH,
+ MediaRootDirectory,
+ &FileNamePart
+ );
+
+ if(DirPathLength >= MAX_PATH) {
+ //
+ // The directory is too large for our buffer. Set our directory
+ // path length to zero so we'll simply bail out in this rare case.
+ //
+ DirPathLength = 0;
+ }
+
+ if(DirPathLength) {
+ //
+ // Strip the filename off the path.
+ //
+ *FileNamePart = L'\0';
+
+ DirPathLength = (DWORD)(FileNamePart - MediaRootDirectory);
+ }
+
+ } else {
+ //
+ // For some reason, we couldn't get the command line arguments that
+ // were used when invoking our setup app. Assume current directory
+ // instead.
+ //
+ DirPathLength = GetCurrentDirectory(MAX_PATH, MediaRootDirectory);
+
+ if(DirPathLength >= MAX_PATH) {
+ //
+ // The current directory is too large for our buffer. Set our
+ // directory path length to zero so we'll simply bail out in this
+ // rare case.
+ //
+ DirPathLength = 0;
+ }
+
+ if(DirPathLength) {
+ //
+ // Ensure that path ends in a path separator character.
+ //
+ if((MediaRootDirectory[DirPathLength-1] != L'\\') &&
+ (MediaRootDirectory[DirPathLength-1] != L'/'))
+ {
+ MediaRootDirectory[DirPathLength++] = L'\\';
+
+ if(DirPathLength < MAX_PATH) {
+ MediaRootDirectory[DirPathLength] = L'\0';
+ } else {
+ //
+ // Not enough room in buffer to add path separator char
+ //
+ DirPathLength = 0;
+ }
+ }
+ }
+ }
+
+ if(ArgList) {
+ GlobalFree(ArgList);
+ }
+
+ if(!DirPathLength) {
+ //
+ // Couldn't figure out what the root directory of our installation
+ // media was. Bail out.
+ //
+ return 0;
+ }
+
+ //
+ // If we're being invoked from a platform-specific subdirectory (i.e.,
+ // \i386 or \ia64), then strip off that subdirectory to get the true media
+ // root path.
+ //
+ if(DirPathLength > TOASTVA_PLATFORM_SUBDIRECTORY_SIZE) {
+ //
+ // We know that the last character in our MediaRootDirectory string is
+ // a path separator character. Check to see if the preceding
+ // characters match our platform-specific subdirectory.
+ //
+ if(!_wcsnicmp(&(MediaRootDirectory[DirPathLength - TOASTVA_PLATFORM_SUBDIRECTORY_SIZE]),
+ TOASTVA_PLATFORM_SUBDIRECTORY,
+ TOASTVA_PLATFORM_SUBDIRECTORY_SIZE - 1)) {
+ //
+ // Platform-specific part matches, just make sure preceding char
+ // is a path separator char.
+ //
+ if((MediaRootDirectory[DirPathLength - TOASTVA_PLATFORM_SUBDIRECTORY_SIZE - 1] == L'\\') ||
+ (MediaRootDirectory[DirPathLength - TOASTVA_PLATFORM_SUBDIRECTORY_SIZE - 1] == L'/')) {
+
+ MediaRootDirectory[DirPathLength - TOASTVA_PLATFORM_SUBDIRECTORY_SIZE] = L'\0';
+ }
+ }
+ }
+
+ DoValueAddWizard(MediaRootDirectory);
+
+ return 0;
+}
diff --git a/general/toaster/toastpkg/toastva/toastva.h b/general/toaster/toastpkg/toastva/toastva.h
new file mode 100644
index 00000000..10ccb508
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/toastva.h
@@ -0,0 +1,79 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ toastva.h
+
+Abstract:
+
+ Header files and resource IDs used by the TOASTVA sample.
+
+--*/
+
+#include <windows.h>
+#include <windowsx.h>
+#include <string.h>
+#include <shellapi.h>
+#include <prsht.h>
+#include <windef.h>
+#include <regstr.h>
+#include <cfgmgr32.h>
+#include <setupapi.h>
+#include <newdev.h>
+#include "resource.h"
+
+//
+// String constants
+//
+#define ENUMERATOR_NAME L"{b85b7c50-6a01-11d2-b841-00c04fad5171}"
+#define HW_ID_TO_UPDATE L"{b85b7c50-6a01-11d2-b841-00c04fad5171}\\MsToaster"
+#define DEVICE_INF_NAME L"toastpkg.inf"
+#define TOASTAPP_SETUP_PATH L"ToastApp\\setup.exe"
+
+//
+// global variables
+//
+extern HINSTANCE g_hInstance;
+
+//
+// utility routines
+//
+BOOL
+IsDeviceInstallInProgress(VOID);
+
+VOID
+MarkDevicesAsNeedReinstall(
+ _In_ HDEVINFO DeviceInfoSet
+ );
+
+DWORD
+GetDeviceConfigFlags(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVINFO_DATA DeviceInfoData
+ );
+
+VOID
+SetDeviceConfigFlags(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVINFO_DATA DeviceInfoData,
+ _In_ DWORD ConfigFlags
+ );
+
+HDEVINFO
+GetNonPresentDevices(
+ _In_ LPCWSTR Enumerator OPTIONAL,
+ _In_ LPCWSTR HardwareID
+ );
+
+VOID
+DoValueAddWizard(
+ _In_ LPCWSTR MediaRootDirectory
+ );
+
diff --git a/general/toaster/toastpkg/toastva/toastva.rc b/general/toaster/toastpkg/toastva/toastva.rc
new file mode 100644
index 00000000..4868ed3b
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/toastva.rc
@@ -0,0 +1,221 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ toastva.rc
+
+Abstract:
+
+ Resources used by the TOASTVA sample.
+
+--*/
+
+#include <windows.h>
+#include "resource.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,0
+ PRODUCTVERSION 1,0,0,0
+ FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+ FILEFLAGS VS_FF_DEBUG
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS VOS_NT_WINDOWS32
+ FILETYPE VFT_APP
+ FILESUBTYPE VFT2_UNKNOWN
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Microsoft Corporation\0"
+ VALUE "FileDescription", "Toaster Value-Add Installer Sample\0"
+ VALUE "FileVersion", "1.00.0000.0\0"
+ VALUE "InternalName", "TOASTVA.EXE\0"
+ VALUE "LegalCopyright", "� Microsoft Corporation. All rights reserved.\0"
+ VALUE "OriginalFilename", "TOASTVA.EXE\0"
+ VALUE "ProductName", "Toaster DDK Sample\0"
+ VALUE "ProductVersion", "1.0.0000.0\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_INTRO DIALOG DISCARDABLE 0, 0, 317, 193
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Toaster"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Welcome to Toasting Made Simple!",IDC_TITLE,115,9,189,
+ 31,NOT WS_GROUP
+ LTEXT "This wizard will help you install supporting software for your toaster, and allow you to choose additional applications that will help you get the most from your new toaster.",
+ IDC_INTRO_TEXT,115,40,189,53
+END
+
+IDD_INTERIOR1 DIALOG DISCARDABLE 0, 0, 317, 143
+STYLE DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION
+FONT 8, "MS Shell Dlg"
+BEGIN
+ CONTROL "Animate1",IDC_ANIMATE1,"SysAnimate32",
+ ACS_TRANSPARENT,148,50,20,20,WS_EX_TRANSPARENT
+END
+
+IDD_END DIALOG DISCARDABLE 0, 0, 317, 193
+STYLE WS_CHILD | WS_DISABLED | WS_CAPTION
+CAPTION "Toaster"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Congratulations! You've successfully installed your new toaster's software.",
+ IDC_TITLE,115,8,195,37
+ LTEXT "Enjoy the toast!",IDC_FINISH_TEXT,115,58,195,128
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_INTRO, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 310
+ VERTGUIDE, 115
+ VERTGUIDE, 304
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 186
+ HORZGUIDE, 8
+ HORZGUIDE, 40
+ END
+
+ IDD_INTERIOR1, DIALOG
+ BEGIN
+ LEFTMARGIN, 28
+ RIGHTMARGIN, 310
+ VERTGUIDE, 28
+ BOTTOMMARGIN, 136
+ END
+
+ IDD_END, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 310
+ VERTGUIDE, 115
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 186
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_BANNER BITMAP DISCARDABLE "header.bmp"
+IDB_WATERMARK BITMAP DISCARDABLE "watermrk.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// AVIs
+//
+
+IDA_SEARCHING AVI "SEARCH.AVI"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+// Icon with lowest ID value placed first to ensure application icon
+// remains consistent on all systems.
+IDI_ICON1 ICON DISCARDABLE "toastapp.ico"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE DISCARDABLE
+BEGIN
+ IDS_TITLE1 "Installing Toaster Support Software"
+ IDS_SUBTITLE1 "Please wait while we install the software that makes your toaster work."
+ IDS_TITLE2 "Choose Additional Applications"
+ IDS_SUBTITLE2 "These applications make it quick and easy to make great toast!"
+ IDS_PROMPT_FOR_HW "You may now plug in your toaster. It will automatically be discovered and configured for you. Enjoy the toast!"
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/general/toaster/toastpkg/toastva/toastva.vcxproj b/general/toaster/toastpkg/toastva/toastva.vcxproj
new file mode 100644
index 00000000..1a25ac8c
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/toastva.vcxproj
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{7A49D840-4E82-477B-8105-CF546E4FD034}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{2DF87D9A-363B-4C6B-9E31-BE2BF60898DF}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>toastva</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>toastva</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>toastva</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>toastva</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib;shell32.lib;comctl32.lib;newdev.lib;.\..\toastco\$(IntDir)\tostrco2.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib;shell32.lib;comctl32.lib;newdev.lib;.\..\toastco\$(IntDir)\tostrco2.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib;shell32.lib;comctl32.lib;newdev.lib;.\..\toastco\$(IntDir)\tostrco2.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ </ClCompile>
+ <Midl>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </Midl>
+ <ResourceCompile>
+ <PreprocessorDefinitions>%(PreprocessorDefinitions);UNICODE;_UNICODE</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib;user32.lib;shell32.lib;comctl32.lib;newdev.lib;.\..\toastco\$(IntDir)\tostrco2.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="toastva.c">
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="util.c">
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ClCompile Include="wizard.c">
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Use</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ <ResourceCompile Include="toastva.rc" />
+ </ItemGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="precompsrc.c">
+ <AdditionalIncludeDirectories>;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreCompiledHeaderFile>precomp.h</PreCompiledHeaderFile>
+ <PreCompiledHeader>Create</PreCompiledHeader>
+ <PreCompiledHeaderOutputFile>$(IntDir)\precomp.pch</PreCompiledHeaderOutputFile>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastva/toastva.vcxproj.Filters b/general/toaster/toastpkg/toastva/toastva.vcxproj.Filters
new file mode 100644
index 00000000..8ae9e8e3
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/toastva.vcxproj.Filters
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{C874EFAD-3886-466E-97CC-4A852797DC29}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{4A7A3632-2660-49C4-9B04-6BD51BEA6316}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{CDCE6E71-5F53-4E60-99F1-ABD1D5819475}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="precompsrc.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="toastva.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="util.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="wizard.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="toastva.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/toastpkg/toastva/util.c b/general/toaster/toastpkg/toastva/util.c
new file mode 100644
index 00000000..e2f68c5b
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/util.c
@@ -0,0 +1,517 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ util.c
+
+Abstract:
+
+ Utility routines used by the TOASTVA sample.
+
+--*/
+
+#include "precomp.h"
+#pragma hdrstop
+
+/*++
+
+ Here's the description for the CMP_WaitNoPendingInstallEvents API used to
+ suppress execution of this app (e.g., via autorun upon CD insertion) while
+ device installation is underway...
+
+ DWORD
+ CMP_WaitNoPendingInstallEvents(
+ _In_ DWORD dwTimeout
+ );
+
+ Routine Description:
+
+ This routine waits until there are no pending device install events.
+ If a timeout value is specified then it will return either when no
+ install events are pending or when the timeout period has expired,
+ whichever comes first. This routine is intended to be called after
+ user-logon, only.
+
+ NOTE: New install events can occur at anytime, this routine just
+ indicates that there are no install events at this moment.
+
+ Parameters:
+
+ dwTimeout - Specifies the time-out interval, in milliseconds. The
+ function returns if the interval elapses, even if there are still
+ pending install events. If dwTimeout is zero, the function just
+ tests whether there are pending install events and returns
+ immediately. If dwTimeout is INFINITE, the function's time-out
+ interval never elapses.
+
+ Return Value:
+
+ If the function succeeds, the return value indicates the event that
+ caused the function to return. If the function fails, the return value
+ is WAIT_FAILED. To get extended error information, call GetLastError.
+ The return value on success is one of the following values:
+
+ WAIT_ABANDONED The specified object is a mutex object that was not
+ released by the thread that owned the mutex object
+ before the owning thread terminated. Ownership of the
+ mutex object is granted to the calling thread, and the
+ mutex is set to nonsignaled.
+ WAIT_OBJECT_0 The state of the specified object is signaled.
+ WAIT_TIMEOUT The time-out interval elapsed, and the object's state is
+ nonsignaled.
+
+--*/
+
+typedef DWORD (WINAPI *CMP_WAITNOPENDINGINSTALLEVENTS_PROC)(
+ _In_ DWORD dwTimeout
+ );
+
+
+BOOL
+IsDeviceInstallInProgress(VOID)
+
+/*++
+
+Routine Description:
+
+ This routine dynamically retrieves the entrypoint to a Windows 2000 (and
+ later) Configuration Manager (CM) API that can be used to detect whether
+ there are presently any device installations in-progress. If this API is
+ not available (it may be obsoleted on future releases of the OS), then the
+ API assumes there are no device installations in progress. This is OK,
+ because future versions of the OS will suppress auto-run when "Found New
+ Hardware" wizard is up, thus eliminating the need for apps to do their own
+ checking.
+
+Arguments:
+
+ none
+
+Return Value:
+
+ If there is presently a device installation in progress, the return value
+ is TRUE.
+
+ If there is not presently a device installation in progress, or we were
+ unsuccessful in retrieving the necessary Configuration Manager API, then
+ the return value is FALSE.
+
+--*/
+
+{
+ HMODULE hModule;
+ CMP_WAITNOPENDINGINSTALLEVENTS_PROC pCMP_WaitNoPendingInstallEvents;
+
+ hModule = GetModuleHandle(L"setupapi.dll");
+
+ if(!hModule) {
+ //
+ // Should never happen since we're linked to setupapi, but...
+ //
+ return FALSE;
+ }
+
+ pCMP_WaitNoPendingInstallEvents =
+ (CMP_WAITNOPENDINGINSTALLEVENTS_PROC)GetProcAddress(
+ hModule,
+ "CMP_WaitNoPendingInstallEvents"
+ );
+ if(!pCMP_WaitNoPendingInstallEvents) {
+ //
+ // We're running on a release of the OS that doesn't supply this API.
+ // Trust the OS to suppress autorun when appropriate.
+ //
+ return FALSE;
+ }
+
+ return (pCMP_WaitNoPendingInstallEvents(0) == WAIT_TIMEOUT);
+}
+
+
+VOID
+MarkDevicesAsNeedReinstall(
+ _In_ HDEVINFO DeviceInfoSet
+ )
+
+/*++
+
+Routine Description:
+
+ This routine enumerates every device information element in the specified
+ list and sets the CONFIGFLAG_REINSTALL registry flag for each one.
+
+Arguments:
+
+ DeviceInfoSet - Supplies a handle to the device information set whose
+ members are to be marked as need-reinstall.
+
+Return Value:
+
+ none
+
+--*/
+
+{
+ SP_DEVINFO_DATA DeviceInfoData;
+ DWORD i, ConfigFlags;
+
+ DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+
+ for(i = 0;
+ SetupDiEnumDeviceInfo(DeviceInfoSet, i, &DeviceInfoData);
+ i++)
+ {
+ ConfigFlags = GetDeviceConfigFlags(DeviceInfoSet, &DeviceInfoData);
+ ConfigFlags |= CONFIGFLAG_REINSTALL;
+ SetDeviceConfigFlags(DeviceInfoSet, &DeviceInfoData, ConfigFlags);
+ }
+}
+
+
+DWORD
+GetDeviceConfigFlags(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVINFO_DATA DeviceInfoData
+ )
+
+/*++
+
+Routine Description:
+
+ This routine retrieves the ConfigFlags registry property for the specified
+ device info element, or zero if the property cannot be retrieved (e.g.,
+ because ConfigFlags haven't yet been set by Found New Hardware process).
+
+Arguments:
+
+ DeviceInfoSet - Supplies a handle to the device information set containing
+ the device of interest.
+
+ DeviceInfoData - Supplies context of a device info element for which
+ ConfigFlags is to be retrieved.
+
+Return Value:
+
+ If device's REG_DWORD ConfigFlags property can be retrieved, it is returned.
+ Otherwise, zero is returned.
+
+--*/
+
+{
+ DWORD ConfigFlags, RegDataType;
+
+ if(!SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
+ DeviceInfoData,
+ SPDRP_CONFIGFLAGS,
+ &RegDataType,
+ (PBYTE)&ConfigFlags,
+ sizeof(ConfigFlags),
+ NULL)
+ || (RegDataType != REG_DWORD))
+ {
+ //
+ // It's possible that this property isn't there, although we should
+ // never enounter other problems like wrong datatype or data length
+ // longer than sizeof(DWORD). In any event, just return zero.
+ //
+ ConfigFlags = 0;
+ }
+
+ return ConfigFlags;
+}
+
+
+VOID
+SetDeviceConfigFlags(
+ _In_ HDEVINFO DeviceInfoSet,
+ _In_ PSP_DEVINFO_DATA DeviceInfoData,
+ _In_ DWORD ConfigFlags
+ )
+
+/*++
+
+Routine Description:
+
+ This routine sets a device's ConfigFlags property to the specified value.
+
+Arguments:
+
+ DeviceInfoSet - Supplies a handle to the device information set containing
+ the device of interest.
+
+ DeviceInfoData - Supplies context of a device info element for which
+ ConfigFlags is to be set.
+
+ ConfigFlags - Specifies the value to be stored to the device's ConfigFlags
+ property.
+
+Return Value:
+
+ none
+
+--*/
+
+{
+ SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
+ DeviceInfoData,
+ SPDRP_CONFIGFLAGS,
+ (PBYTE)&ConfigFlags,
+ sizeof(ConfigFlags)
+ );
+}
+
+
+HDEVINFO
+GetNonPresentDevices(
+ _In_ LPCWSTR Enumerator OPTIONAL,
+ _In_ LPCWSTR HardwareID
+ )
+
+/*++
+
+Routine Description:
+
+ This routine retrieves any non-present devices matching the specified
+ criteria, and returns them in a device information set.
+
+Arguments:
+
+ Enumerator - Optionally, supplies the name of the Enumerator under which
+ this device may be found. If the device may show up under more than
+ one enumerator, the routine can be called with Enumerator specified as
+ NULL, in which case all device instances in the registry are examined.
+
+ HardwareID - Supplies the hardware ID to be searched for. This will be
+ compared against each of the hardware IDs for all device instances in
+ the system (potentially filtered based on Enumerator), present or not.
+
+Return Value:
+
+ If any non-present devices are discovered, this routine returns a device
+ information set containing those devices. This set must be freed via
+ SetupDiDestroyDeviceInfoList by the caller.
+
+ If no such devices are encountered (or if an error occurs), the return
+ value is INVALID_HANDLE_VALUE. GetLastError will indicate the cause of
+ failure.
+
+--*/
+
+{
+ HDEVINFO AllDevs, ExistingNonPresentDevices;
+ DWORD i, Err;
+ SP_DEVINFO_DATA DeviceInfoData;
+ LPWSTR HwIdBuffer, CurId;
+ DWORD HwIdBufferLen, RegDataType, RequiredSize;
+ BOOL bRet;
+ ULONG Status, Problem;
+ TCHAR DeviceInstanceId[MAX_DEVNODE_ID_LEN];
+
+ ExistingNonPresentDevices = INVALID_HANDLE_VALUE;
+
+ AllDevs = SetupDiGetClassDevs(NULL,
+ Enumerator,
+ NULL,
+ DIGCF_ALLCLASSES
+ );
+
+ if(AllDevs == INVALID_HANDLE_VALUE) {
+ //
+ // last error has already been set during the above call.
+ //
+ return INVALID_HANDLE_VALUE;
+ }
+
+ //
+ // Iterate through each device we found, comparing its hardware ID(s)
+ // against the one we were passed in.
+ //
+ DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
+
+ HwIdBuffer = NULL;
+ HwIdBufferLen = 0;
+ Err = NO_ERROR;
+ bRet = FALSE;
+
+ i = 0;
+
+ while(SetupDiEnumDeviceInfo(AllDevs, i, &DeviceInfoData)) {
+ //
+ // Retrieve the HardwareID property for this device info element
+ //
+ if(!SetupDiGetDeviceRegistryProperty(AllDevs,
+ &DeviceInfoData,
+ SPDRP_HARDWAREID,
+ &RegDataType,
+ (PBYTE)HwIdBuffer,
+ HwIdBufferLen,
+ &RequiredSize)) {
+ //
+ // If the failure was due to buffer-too-small, we can resize and
+ // try again.
+ //
+ if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+
+ if(HwIdBuffer) {
+ GlobalFree(HwIdBuffer);
+ }
+
+ HwIdBuffer = GlobalAlloc(0, RequiredSize);
+ if(HwIdBuffer) {
+ HwIdBufferLen = RequiredSize;
+ //
+ // try again
+ //
+ continue;
+ } else {
+ //
+ // We failed to allocate the buffer we needed. This is
+ // considered a critical failure that should cause us to
+ // bail.
+ //
+ Err = ERROR_NOT_ENOUGH_MEMORY;
+ break;
+ }
+
+ } else {
+ //
+ // We failed to retrieve the property for some other reason.
+ // Skip this device and move on to the next.
+ //
+ i++;
+ continue;
+ }
+ }
+
+ if((RegDataType != REG_MULTI_SZ) || (RequiredSize < sizeof(TCHAR))) {
+ //
+ // Data is invalid--this should never happen, but we'll skip the
+ // device in this case...
+ //
+ i++;
+ continue;
+ }
+
+ //
+ // If we get to here, then we successfully retrieved the multi-sz
+ // hardware id list for this device. Compare each of those IDs with
+ // the caller-supplied one.
+ //
+ for(CurId = HwIdBuffer; CurId && *CurId; CurId += (lstrlen(CurId) + 1)) {
+
+ if(!lstrcmpi(CurId, HardwareID)) {
+ //
+ // We found a match!
+ //
+ bRet = TRUE;
+
+ //
+ // If the device isn't currently present (as indicated by
+ // failure to retrieve its status), then add it to the list of
+ // such devices to be returned to the caller.
+ //
+ if(CR_SUCCESS != CM_Get_DevNode_Status(&Status,
+ &Problem,
+ (DEVNODE)DeviceInfoData.DevInst,
+ 0))
+ {
+ if(ExistingNonPresentDevices == INVALID_HANDLE_VALUE) {
+ //
+ // This is the first non-present device we've
+ // encountered--we need to create the HDEVINFO set.
+ //
+ ExistingNonPresentDevices =
+ SetupDiCreateDeviceInfoList(NULL, NULL);
+
+ if(ExistingNonPresentDevices == INVALID_HANDLE_VALUE) {
+ //
+ // Failure to create this set is a critical error!
+ //
+ Err = GetLastError();
+ bRet = FALSE;
+ break;
+ }
+ }
+
+ //
+ // We need to get the device instance's name so we can
+ // open it up into our "non-present devices" list
+ //
+ if(!SetupDiGetDeviceInstanceId(AllDevs,
+ &DeviceInfoData,
+ DeviceInstanceId,
+ sizeof(DeviceInstanceId) / sizeof(TCHAR),
+ NULL)) {
+ //
+ // Should never fail, but considered critical if it
+ // does...
+ //
+ Err = GetLastError();
+ bRet = FALSE;
+ break;
+ }
+
+ //
+ // Now open up the non-present device into our list.
+ //
+ if(!SetupDiOpenDeviceInfo(ExistingNonPresentDevices,
+ DeviceInstanceId,
+ NULL,
+ 0,
+ NULL)) {
+ //
+ // This failure is also considered critical!
+ //
+ Err = GetLastError();
+ bRet = FALSE;
+ }
+
+ break;
+ }
+ }
+ }
+
+ if(Err != NO_ERROR) {
+ //
+ // Critical error encountered--bail!
+ //
+ break;
+ }
+
+ //
+ // Move onto the next device instance
+ //
+ i++;
+ }
+
+ if(HwIdBuffer) {
+ GlobalFree(HwIdBuffer);
+ }
+
+ //
+ // We can now destroy our temporary list of all devices under consideration
+ //
+ SetupDiDestroyDeviceInfoList(AllDevs);
+
+ if((Err != NO_ERROR) &&
+ (ExistingNonPresentDevices != INVALID_HANDLE_VALUE)) {
+ //
+ // We encountered a critical error, so we need to destroy the (partial)
+ // list of non-present devices we'd built.
+ //
+ SetupDiDestroyDeviceInfoList(ExistingNonPresentDevices);
+ ExistingNonPresentDevices = INVALID_HANDLE_VALUE;
+ }
+
+ SetLastError(Err);
+
+ return ExistingNonPresentDevices;
+}
+
diff --git a/general/toaster/toastpkg/toastva/watermrk.bmp b/general/toaster/toastpkg/toastva/watermrk.bmp
new file mode 100644
index 00000000..5749637d
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/watermrk.bmp
Binary files differ
diff --git a/general/toaster/toastpkg/toastva/wizard.c b/general/toaster/toastpkg/toastva/wizard.c
new file mode 100644
index 00000000..5f876a3f
--- /dev/null
+++ b/general/toaster/toastpkg/toastva/wizard.c
@@ -0,0 +1,883 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ wizard.c
+
+Abstract:
+
+ This module implements the TOASTVA wizard that installs/updates toaster
+ drivers and allows the user to select additional value-added software.
+
+--*/
+
+#include "precomp.h"
+#pragma hdrstop
+
+//
+// Constants
+//
+#define WMX_UPDATE_DRIVER_DONE (WM_USER + 500)
+
+//
+// Structures
+//
+typedef struct _SHAREDWIZDATA {
+ HFONT hTitleFont; // Title font for the Welcome and Completion pages
+ BOOL HwInsertedFirst; // Is the hardware already present?
+ LPCWSTR MediaRootDirectory; // Fully-qualified path to root of install media
+ BOOL DoDriverUpdatePage; // Should Update Driver page do anything?
+ BOOL RebootRequired; // Did we do anything that requires a reboot?
+ HWND hwndDlg; // Handle to dialog notified by drv update thread
+} SHAREDWIZDATA, *LPSHAREDWIZDATA;
+
+//
+// Function prototypes
+//
+INT_PTR
+CALLBACK
+IntroDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ );
+
+INT_PTR
+CALLBACK
+IntPage1DlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ );
+
+INT_PTR
+CALLBACK
+EndDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ );
+
+DWORD
+WINAPI
+UpdateDriverThreadProc(
+ _In_ LPVOID ThreadData
+ );
+
+INT
+CALLBACK
+WizardCallback(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ LPARAM lParam
+ );
+
+//
+// Prototype for a routine exported from toastco.dll
+//
+HPROPSHEETPAGE
+GetValueAddSoftwareWizPage(
+ _In_ LPCWSTR MediaRootDirectory,
+ _In_opt_ LPCWSTR MediaDiskName,
+ _In_opt_ LPCWSTR MediaTagFile
+ );
+
+//
+// Implementation
+//
+
+VOID
+DoValueAddWizard(
+ _In_ LPCWSTR MediaRootDirectory
+ )
+
+/*++
+
+Routine Description:
+
+ This routine displays a wizard that steps the user through the following
+ actions:
+
+ (a) Performs a "driver update" for any currently-present toasters
+ (b) Installs the INF and CAT in case no toasters presently exist
+ (c) Optionally, installs value-add software selected by the user (this
+ wizard page is retrieved from the toaster co-installer, and is the same
+ page the user gets if they do a "hardware-first" installation using our
+ driver).
+
+Arguments:
+
+ MediaRootDirectory - Supplies the fully-qualified path to the root
+ directory where the installation media is located.
+
+Return Value:
+
+ none
+
+--*/
+
+{
+ PROPSHEETPAGE psp = {0}; //defines the property sheet pages
+ HPROPSHEETPAGE ahpsp[4] = {0}; //an array to hold the page's HPROPSHEETPAGE handles
+ PROPSHEETHEADER psh = {0}; //defines the property sheet
+ SHAREDWIZDATA wizdata = {0}; //the shared data structure
+
+ NONCLIENTMETRICS ncm = {0};
+ LOGFONT TitleLogFont;
+ HDC hdc;
+ INT FontSize;
+ INT index = 0;
+ HRESULT hr;
+
+ //
+ //Create the Wizard pages
+ //
+ // Intro page...
+ //
+ psp.dwSize = sizeof(psp);
+ psp.dwFlags = PSP_DEFAULT|PSP_HIDEHEADER;
+ psp.hInstance = g_hInstance;
+ psp.lParam = (LPARAM) &wizdata; //The shared data structure
+ psp.pfnDlgProc = IntroDlgProc;
+ psp.pszTemplate = MAKEINTRESOURCE(IDD_INTRO);
+
+ ahpsp[index++] = CreatePropertySheetPage(&psp);
+
+ //
+ // Updating drivers page...
+ //
+ psp.dwFlags = PSP_DEFAULT|PSP_USEHEADERTITLE|PSP_USEHEADERSUBTITLE|PSP_USETITLE;
+ psp.pszHeaderTitle = MAKEINTRESOURCE(IDS_TITLE1);
+ psp.pszHeaderSubTitle = MAKEINTRESOURCE(IDS_SUBTITLE1);
+ psp.pszTemplate = MAKEINTRESOURCE(IDD_INTERIOR1);
+ psp.pfnDlgProc = IntPage1DlgProc;
+
+ ahpsp[index++] = CreatePropertySheetPage(&psp);
+
+ //
+ // Retrieve the value-add software chooser page from the toaster
+ // co-installer (toastco.dll).
+ //
+ ahpsp[index] = GetValueAddSoftwareWizPage(MediaRootDirectory, NULL, NULL);
+
+ if(ahpsp[index]) {
+ index++;
+ }
+
+ //
+ // Finish page...
+ //
+ psp.dwFlags = PSP_DEFAULT|PSP_HIDEHEADER;
+ psp.pszTemplate = MAKEINTRESOURCE(IDD_END);
+ psp.pfnDlgProc = EndDlgProc;
+
+ ahpsp[index] = CreatePropertySheetPage(&psp);
+
+ //
+ // Create the property sheet...
+ //
+ psh.dwSize = sizeof(psh);
+ psh.hInstance = g_hInstance;
+ psh.hwndParent = NULL;
+ psh.phpage = ahpsp;
+ psh.dwFlags = PSH_WIZARD97|PSH_WATERMARK|PSH_HEADER|PSH_STRETCHWATERMARK|PSH_WIZARD|PSH_USECALLBACK;
+ psh.pszbmWatermark = MAKEINTRESOURCE(IDB_WATERMARK);
+ psh.pszbmHeader = MAKEINTRESOURCE(IDB_BANNER);
+ psh.nStartPage = 0;
+ psh.nPages = 4;
+ psh.pfnCallback = WizardCallback;
+
+ //
+ // Set up the font for the titles on the intro and ending pages
+ //
+ ncm.cbSize = sizeof(ncm);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
+
+ //
+ // Create the intro/end title font
+ //
+ TitleLogFont = ncm.lfMessageFont;
+ TitleLogFont.lfWeight = FW_BOLD;
+ hr = StringCchCopy(TitleLogFont.lfFaceName, LF_FACESIZE, L"Verdana Bold");
+ if(SUCCEEDED(hr) == FALSE) {
+ return; // assert
+ }
+
+ hdc = GetDC(NULL); //gets the screen DC
+ FontSize = 12;
+ TitleLogFont.lfHeight = 0 - GetDeviceCaps(hdc, LOGPIXELSY) * FontSize / 72;
+ wizdata.hTitleFont = CreateFontIndirect(&TitleLogFont);
+ ReleaseDC(NULL, hdc);
+ wizdata.MediaRootDirectory = MediaRootDirectory;
+
+ //
+ // Display the wizard
+ //
+ PropertySheet(&psh);
+
+ //
+ // Destroy the fonts
+ //
+ DeleteObject(wizdata.hTitleFont);
+
+ //
+ // If we did anything that requires a reboot, prompt the user
+ // now. Note that we need to do this regardle
+ //
+ if(wizdata.RebootRequired) {
+ SetupPromptReboot(NULL, NULL, FALSE);
+ }
+}
+
+
+INT_PTR
+CALLBACK
+IntroDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+
+/*++
+
+Routine Description:
+
+ This function is the dialog procedure for the Welcome page of the wizard.
+
+Arguments:
+
+ hwndDlg - Supplies a handle to the dialog box window
+
+ uMsg - Supplies the message
+
+ wParam - Supplies the first message parameter
+
+ lParam - Supplies the second message parameter
+
+Return Value:
+
+ This dialog procedure always returns zero.
+
+--*/
+
+{
+ LPSHAREDWIZDATA pdata;
+ LPNMHDR lpnm;
+
+ UNREFERENCED_PARAMETER( wParam );
+
+ //
+ // Retrieve the shared user data from GWL_USERDATA
+ //
+ pdata = (LPSHAREDWIZDATA) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch(uMsg) {
+
+ case WM_INITDIALOG :
+ {
+ HWND hwndControl;
+
+ //
+ // Get the shared data from PROPSHEETPAGE lParam valueand load
+ // it into GWL_USERDATA
+ //
+ pdata = (LPSHAREDWIZDATA) ((LPPROPSHEETPAGE) lParam) -> lParam;
+
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pdata);
+
+ //
+ // It's an intro/end page, so get the title font from the
+ // shared data and use it for the title control
+ //
+ hwndControl = GetDlgItem(hwndDlg, IDC_TITLE);
+ SetWindowFont(hwndControl,pdata->hTitleFont, TRUE);
+ break;
+ }
+
+ case WM_NOTIFY :
+
+ lpnm = (LPNMHDR)lParam;
+
+ switch(lpnm->code) {
+
+ case PSN_SETACTIVE :
+ //
+ // Enable the Next button
+ //
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
+
+ //
+ // When we're moving forward through the wizard, we want
+ // the driver update page to do its work.
+ //
+ pdata->DoDriverUpdatePage = TRUE;
+ break;
+
+ case PSN_WIZNEXT :
+ //Handle a Next button click here
+ break;
+
+ case PSN_RESET :
+ //Handle a Cancel button click, if necessary
+ break;
+
+ default :
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+
+INT_PTR
+CALLBACK
+IntPage1DlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+
+/*++
+
+Routine Description:
+
+ This function is the dialog procedure for the first interior wizard page.
+ This page updates the drivers for any existing (present) devices, or
+ installs the INF if there aren't any present devices.
+
+Arguments:
+
+ hwndDlg - Supplies a handle to the dialog box window
+
+ uMsg - Supplies the message
+
+ wParam - Supplies the first message parameter
+
+ lParam - Supplies the second message parameter
+
+Return Value:
+
+ This dialog procedure always returns zero.
+
+--*/
+
+{
+ LPSHAREDWIZDATA pdata;
+ LPNMHDR lpnm;
+ HANDLE hThread;
+ HKEY hKey;
+ DWORD UserPrompted;
+
+ UNREFERENCED_PARAMETER( wParam );
+
+ //
+ // Retrieve the shared user data from GWL_USERDATA
+ //
+ pdata = (LPSHAREDWIZDATA) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch(uMsg) {
+
+ case WM_INITDIALOG :
+ //
+ // Get the PROPSHEETPAGE lParam value and load it into GWL_USERDATA
+ //
+ pdata = (LPSHAREDWIZDATA) ((LPPROPSHEETPAGE) lParam) -> lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pdata);
+ break;
+
+ case WM_NOTIFY :
+
+ lpnm = (LPNMHDR)lParam;
+
+ switch(lpnm->code) {
+
+ case PSN_SETACTIVE :
+ //
+ // If we're coming here from the intro page, then disable
+ // the Back and Next buttons (we're going to be busy for a
+ // little bit updating drivers).
+ //
+ // If we're coming to this page from anywhere else,
+ // immediately jump to the intro page.
+ //
+ if(pdata->DoDriverUpdatePage) {
+ //
+ // Reset our flag so that we won't try this again if we
+ // go to later pages, then come back to this one. (We
+ // only do anything when the wizard page is accessed in
+ // the forward direction, from the Intro page.)
+ //
+ pdata->DoDriverUpdatePage = FALSE;
+
+ //
+ // Set our "UserPrompted" registry flag so the
+ // co-installer won't popup its own value-add software
+ // chooser page during driver update.
+ //
+ if(ERROR_SUCCESS == RegCreateKeyEx(
+ HKEY_LOCAL_MACHINE,
+ TEXT("SOFTWARE\\Microsoft\\Toaster"),
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_READ | KEY_WRITE,
+ NULL,
+ &hKey,
+ NULL)) {
+
+ UserPrompted = 1;
+ RegSetValueEx(hKey,
+ TEXT("User Prompted"),
+ 0,
+ REG_DWORD,
+ (PBYTE)&UserPrompted,
+ sizeof(UserPrompted)
+ );
+
+ RegCloseKey(hKey);
+ }
+
+ //
+ // Disable Next, Back, and Cancel
+ //
+ PropSheet_SetWizButtons(GetParent(hwndDlg), 0);
+ EnableWindow(GetDlgItem(GetParent(hwndDlg), IDCANCEL), FALSE);
+
+ //
+ // Show "searching" animation...
+ //
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ANIMATE1), SW_SHOW);
+ Animate_Open(GetDlgItem(hwndDlg, IDC_ANIMATE1), MAKEINTRESOURCE(IDA_SEARCHING));
+ Animate_Play(GetDlgItem(hwndDlg, IDC_ANIMATE1), 0, -1, -1);
+
+ //
+ // Create a thread to do the work of updating the
+ // driver, etc.
+ //
+ pdata->hwndDlg = hwndDlg;
+
+ hThread = CreateThread(NULL,
+ 0,
+ UpdateDriverThreadProc,
+ pdata,
+ 0,
+ NULL
+ );
+
+ if(hThread) {
+ //
+ // Thread launched successfully--close the handle,
+ // then just wait to be notified of thread's
+ // completion.
+ //
+ CloseHandle(hThread);
+
+ } else {
+ //
+ // Couldn't launch the thread--just move on to the
+ // value-add software page.
+ //
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
+ PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
+ }
+
+ } else {
+ //
+ // We're coming "back" to this page. Skip it, and go
+ // to the intro page.
+ //
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK);
+ PropSheet_PressButton(GetParent(hwndDlg), PSBTN_BACK);
+ }
+ break;
+
+ case PSN_WIZNEXT :
+ //Handle a Next button click, if necessary
+ break;
+
+ case PSN_WIZBACK :
+ //Handle a Back button click, if necessary
+ break;
+
+ case PSN_RESET :
+ //Handle a Cancel button click, if necessary
+ break;
+
+ default :
+ break;
+ }
+ break;
+
+ case WMX_UPDATE_DRIVER_DONE :
+ //
+ // Stop "searching" animation...
+ //
+ Animate_Stop(GetDlgItem(hwndDlg, IDC_ANIMATE1));
+ ShowWindow(GetDlgItem(hwndDlg, IDC_ANIMATE1), SW_HIDE);
+
+ //
+ // Regardless of whether we succeeded in upgrading any drivers, we'll
+ // go ahead and proceed to the value-add software page.
+ //
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT);
+ EnableWindow(GetDlgItem(GetParent(hwndDlg), IDCANCEL), TRUE);
+
+ PropSheet_PressButton(GetParent(hwndDlg), PSBTN_NEXT);
+
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+
+INT_PTR
+CALLBACK
+EndDlgProc(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ WPARAM wParam,
+ _In_ LPARAM lParam
+ )
+
+/*++
+
+Routine Description:
+
+ This function is the dialog procedure for the Finish page of the wizard.
+
+Arguments:
+
+ hwndDlg - Supplies a handle to the dialog box window
+
+ uMsg - Supplies the message
+
+ wParam - Supplies the first message parameter
+
+ lParam - Supplies the second message parameter
+
+Return Value:
+
+ This dialog procedure always returns zero.
+
+--*/
+
+{
+ LPSHAREDWIZDATA pdata;
+ LPNMHDR lpnm;
+
+ UNREFERENCED_PARAMETER( wParam );
+
+ //
+ // Retrieve the shared user data from GWL_USERDATA
+ //
+ pdata = (LPSHAREDWIZDATA) GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
+
+ switch(uMsg) {
+
+ case WM_INITDIALOG :
+ {
+ HWND hwndControl;
+
+ //
+ // Get the shared data from PROPSHEETPAGE lParam value and load
+ // it into GWL_USERDATA
+ //
+ pdata = (LPSHAREDWIZDATA) ((LPPROPSHEETPAGE) lParam) -> lParam;
+ SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR) pdata);
+
+ //
+ // It's an intro/end page, so get the title font from userdata
+ // and use it on the title control
+ //
+ hwndControl = GetDlgItem(hwndDlg, IDC_TITLE);
+ SetWindowFont(hwndControl,pdata->hTitleFont, TRUE);
+ break;
+ }
+
+ case WM_NOTIFY :
+
+ lpnm = (LPNMHDR)lParam;
+
+ switch(lpnm->code) {
+
+ case PSN_SETACTIVE :
+ //
+ // Enable the correct buttons for the active page
+ //
+ PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK | PSWIZB_FINISH);
+
+ //
+ // Doesn't make sense to have Cancel button enabled here
+ //
+ EnableWindow(GetDlgItem(GetParent(hwndDlg), IDCANCEL), FALSE);
+
+ //
+ // If we didn't find any currently-present devices, then prompt
+ // the user to insert their device now.
+ //
+ if(!pdata->HwInsertedFirst) {
+
+ WCHAR TempString[LINE_LEN];
+
+ if(LoadString(g_hInstance,
+ IDS_PROMPT_FOR_HW,
+ TempString,
+ sizeof(TempString) / sizeof(WCHAR))) {
+
+ SetDlgItemText(hwndDlg, IDC_FINISH_TEXT, TempString);
+ }
+ }
+
+ break;
+
+ case PSN_WIZBACK :
+ //
+ // Jumping back from this page, so turn Cancel button back on.
+ //
+ EnableWindow(GetDlgItem(GetParent(hwndDlg), IDCANCEL), TRUE);
+ break;
+
+ default :
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+
+DWORD
+WINAPI
+UpdateDriverThreadProc(
+ _In_ LPVOID ThreadData
+ )
+
+/*++
+
+Routine Description:
+
+ This function updates the drivers for any existing toasters. If there are
+ no toasters currently connected to the computer, it installs the INF/CAT so
+ that the system will be ready to automatically install toasters that are
+ plugged in later. This routine will also mark any non-present (aka,
+ "phantom") toasters as needs-reinstall, so that they'll be updated to the
+ new driver if they're ever plugged in again.
+
+Arguments:
+
+ ThreadData - Supplies a pointer to a SHAREDWIZDATA structure that's used
+ both by this thread, and by the wizard in the main thread.
+
+Return Value:
+
+ If successful, the function returns NO_ERROR.
+
+ Otherwise, the function returns a Win32 error code indicating the cause of
+ failure.
+
+--*/
+
+{
+ DWORD Err;
+ LPSHAREDWIZDATA pdata;
+ WCHAR FullInfPath[MAX_PATH];
+ HDEVINFO ExistingNonPresentDevices;
+
+
+ pdata = (LPSHAREDWIZDATA)ThreadData;
+ Err = NO_ERROR;
+
+ //
+ // First, attempt to update any present devices to our driver...
+ //
+ if (FAILED(StringCchCopy(FullInfPath, MAX_PATH, pdata->MediaRootDirectory))) {
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ if (FAILED(StringCchCat(FullInfPath, MAX_PATH, DEVICE_INF_NAME))) {
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ if(UpdateDriverForPlugAndPlayDevices(GetParent(pdata->hwndDlg),
+ HW_ID_TO_UPDATE,
+ FullInfPath,
+ 0,
+ &pdata->RebootRequired)) {
+ //
+ // We know that at least one device existed, and was upgraded.
+ //
+ pdata->HwInsertedFirst = TRUE;
+
+ } else {
+
+ Err = GetLastError();
+
+ //
+ // We failed to update the driver. If we failed simply because
+ // there were no toasters currently attached to the computer, then
+ // we still want to install the INF.
+ //
+ if(Err == ERROR_NO_SUCH_DEVINST) {
+
+ pdata->HwInsertedFirst = FALSE;
+
+ //
+ // Since we didn't do any device installs, the INF (and CAT)
+ // didn't get automatically installed. We'll install them now,
+ // so that they'll be present when the user subsequently plugs
+ // their hardware in.
+ //
+ if(!SetupCopyOEMInf(FullInfPath,
+ NULL,
+ SPOST_PATH,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ NULL)) {
+ //
+ // Failure to install the INF is more important (worse) than
+ // the absence of any devices!
+ //
+ Err = GetLastError();
+ }
+
+ } else {
+ //
+ // Apparently there _were_ existing devices--we just failed to
+ // upgrade their drivers. This might be due to an installation
+ // problem, or perhaps because the devices already have drivers
+ // newer than the one we offered.
+ //
+ pdata->HwInsertedFirst = TRUE;
+ }
+ }
+
+ if((Err == NO_ERROR) || (Err == ERROR_NO_SUCH_DEVINST)) {
+ //
+ // Either we successfully upgraded one or more toasters, or there were
+ // no present toasters but we successfully installed our INF and CAT.
+ //
+ // There may exist, however, devices that were once connected to the
+ // computer, but presently are not. If such devices are connected
+ // again in the future, we want to ensure they go through device
+ // installation. We will retrieve the list of non-present devices, and
+ // mark each as "needs re-install" to kick them back through the "New
+ // Hardware Found" process if they ever show up again. (Note that this
+ // doesn't destroy any device-specific settings they may have, so this
+ // is just forcing an upgrade, not an uninstall/re-install.)
+ //
+ // (The HardwareID used is the one defined for the toaster sample,
+ // BUS_HARDWARE_IDS in src\general\toaster\bus\common.h. We also take
+ // advantage of the fact that we know these devices will always be
+ // enumerated under the "{b85b7c50-6a01-11d2-b841-00c04fad5171}"
+ // enum namespace.)
+ //
+ ExistingNonPresentDevices = GetNonPresentDevices(ENUMERATOR_NAME,
+ HW_ID_TO_UPDATE
+ );
+
+ if(ExistingNonPresentDevices != INVALID_HANDLE_VALUE) {
+
+ MarkDevicesAsNeedReinstall(ExistingNonPresentDevices);
+
+ SetupDiDestroyDeviceInfoList(ExistingNonPresentDevices);
+ }
+ }
+
+ PostMessage(pdata->hwndDlg, WMX_UPDATE_DRIVER_DONE, 0, 0);
+
+ return Err;
+}
+
+
+INT
+CALLBACK
+WizardCallback(
+ _In_ HWND hwndDlg,
+ _In_ UINT uMsg,
+ _In_ LPARAM lParam
+ )
+
+/*++
+
+Routine Description:
+
+ Call back used to remove the "X" and "?" from the wizard page.
+
+Arguments:
+
+ hwndDlg - Handle to the property sheet dialog box.
+
+ uMsg - Identifies the message being received. This parameter is one of the
+ following values:
+
+ PSCB_INITIALIZED - Indicates that the property sheet is being
+ initialized. The lParam value is zero for this
+ message.
+
+ PSCB_PRECREATE - Indicates that the property sheet is about to be
+ created. The hwndDlg parameter is NULL and the
+ lParam parameter is a pointer to a dialog template
+ in memory. This template is in the form of a
+ DLGTEMPLATE structure followed by one or more
+ DLGITEMTEMPLATE structures.
+
+ lParam - Specifies additional information about the message. The
+ meaning of this value depends on the uMsg parameter.
+
+Return Value:
+
+ The function returns zero.
+
+--*/
+
+{
+ DLGTEMPLATE *pDlgTemplate;
+
+ UNREFERENCED_PARAMETER( hwndDlg );
+
+ switch(uMsg) {
+
+ case PSCB_PRECREATE:
+ if(lParam){
+ //
+ // This is done to hide the X and ? at the top of the wizard
+ //
+ pDlgTemplate = (DLGTEMPLATE *)lParam;
+ pDlgTemplate->style &= ~(DS_CONTEXTHELP | WS_SYSMENU);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
diff --git a/general/toaster/umdf2/Package/package.VcxProj b/general/toaster/umdf2/Package/package.VcxProj
new file mode 100644
index 00000000..d03cefec
--- /dev/null
+++ b/general/toaster/umdf2/Package/package.VcxProj
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="PropertySheets">
+ <PlatformToolset>WindowsKernelModeDriver10.0</PlatformToolset>
+ <ConfigurationType>Utility</ConfigurationType>
+ <DriverType>Package</DriverType>
+ <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
+ <Configuration>Debug</Configuration>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}</ProjectGuid>
+ <SampleGuid>{7F090110-1487-4DA8-8CEA-3C1A43F8C119}</SampleGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup />
+ <PropertyGroup>
+ <DebuggerFlavor>DbgengRemoteDebugger</DebuggerFlavor>
+ <ImportToStore>False</ImportToStore>
+ <InstallMode>None</InstallMode>
+ <HardwareIdString />
+ <CommandLine />
+ <ScriptPath />
+ <DeployFiles />
+ <ScriptName />
+ <ScriptDeviceQuery>%PathToInf%</ScriptDeviceQuery>
+ <EnableVerifier>False</EnableVerifier>
+ <AllDrivers>False</AllDrivers>
+ <VerifyProjectOutput>True</VerifyProjectOutput>
+ <VerifyDrivers />
+ <VerifyFlags>133563</VerifyFlags>
+ </PropertyGroup>
+ <ItemDefinitionGroup>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <!--Inf Include="DriverInf.inv" /-->
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\filter\generic\filterum.vcxproj">
+ <Project>{A60F76D2-C512-4DA6-8C80-263F1B506267}</Project>
+ </ProjectReference>
+ <ProjectReference Include="..\func\simple\wdfsimpleum.vcxproj">
+ <Project>{4867F54B-D8EF-45B0-984E-D571D987174A}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/Package/package.VcxProj.Filters b/general/toaster/umdf2/Package/package.VcxProj.Filters
new file mode 100644
index 00000000..8153ab30
--- /dev/null
+++ b/general/toaster/umdf2/Package/package.VcxProj.Filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{1B3C45DA-0194-4257-B308-970F7B2AB7C0}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{84FCFB7D-58FA-4617-9482-C1BD332BCC31}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{824C0178-16B0-4768-B411-CE9BDD79D690}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{9C6B14B3-304F-491F-B5F1-C14CA36EC7E8}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/ReadMe.md b/general/toaster/umdf2/ReadMe.md
new file mode 100644
index 00000000..8bd9dada
--- /dev/null
+++ b/general/toaster/umdf2/ReadMe.md
@@ -0,0 +1,58 @@
+Toaster Sample (UMDF Version 2)
+===============================
+
+The Toaster (UMDF version 2) sample is an iterative series of samples that demonstrate fundamental aspects of Windows driver development.
+
+The Toaster sample collection is comprised of driver projects (.vcxproj files) that are contained in the umdf2toaster.sln solution file.
+
+For related information, see the [Toaster Sample](http://code.msdn.microsoft.com/windowshardware/Toaster-7d256224).
+
+## Universal Compliant
+This sample builds a Windows Universal driver. It uses only APIs and DDIs that are included in Windows Core.
+
+Related technologies
+--------------------
+
+[User-Mode Driver Framework](http://msdn.microsoft.com/en-us/library/windows/hardware/ff560456)
+
+Run the sample
+--------------
+
+The computer where you install the driver is called the *target computer* or the *test computer*. Typically this is a separate computer from where you develop and build the driver package. The computer where you develop and build the driver is called the *host computer*.
+
+The process of moving the driver package to the target computer and installing the driver is called *deploying the driver*. You can deploy a driver sample automatically or manually.
+
+### Automatic deployment (root enumerated)
+
+Before you automatically deploy a driver, you must provision the target computer. For instructions, see [Configuring a Computer for Driver Deployment, Testing, and Debugging](http://msdn.microsoft.com/en-us/library/windows/hardware/).
+
+1. On the host computer, in Visual Studio, in Solution Explorer, right click **package** (lower case), and choose **Properties**. Navigate to **Configuration Properties \> Driver Install \> Deployment**.
+2. Check **Enable deployment**, and check **Remove previous driver versions before deployment**. For **Target Computer Name**, select the name of a target computer that you provisioned previously. Select **Hardware ID Driver Update**, and enter **root\\toaster** for the hardware ID. Click **OK**.
+3. Because this solution contains many projects, you may find it easier to remove some of them before you build and deploy a driver package. To do so, right click **package** (lower case), and choose **Properties**. Navigate to **Common Properties-\>References** and click **Remove Reference** to remove projects you don't want. (You can add them back later by using **Add New Reference**.) Click **OK**.
+4. On the **Build** menu, choose **Build Solution** or **Rebuild Solution** (if you removed references).
+5. If you removed references and deployment does not succeed, try deleting the contents of the c:\\DriverTest\\Drivers folder on the target machine, and then retry deployment.
+
+### Manual deployment (root enumerated)
+
+Before you manually deploy a driver, you must turn on test signing and install a certificate on the target computer. You also need to copy the [DevCon](http://msdn.microsoft.com/en-us/library/windows/hardware/ff544707) tool to the target computer. For instructions, see [Preparing a Computer for Manual Driver Deployment](http://msdn.microsoft.com/en-us/library/windows/hardware/dn265571).
+
+1. Copy all of the files in your driver package to a folder on the target computer (for example, c:\\Umdf2toaster).
+2. On the target computer, open a Command Prompt window as Administrator. Navigate to your driver package folder, and enter a command such as:
+
+ **devcon install wdfsimpleum.inf root\\toaster**
+
+### View the root enumerated driver in Device Manager
+
+On the target computer, in a Command Prompt window, enter **devmgmt** to open Device Manager. In Device Manager, on the **View** menu, choose **Devices by type**. In the device tree, locate **Sample WDF Toaster Service + Filter** (for example, this might be under the **Toaster** node).
+
+In Device Manager, on the **View** menu, choose **Devices by connection**. Locate **Sample WDF Toaster Service + Filter** as a child of the root node of the device tree.
+
+Build the sample using MSBuild
+------------------------------
+
+As an alternative to building the driver sample in Visual Studio, you can build it in a Visual Studio Command Prompt window. In Visual Studio, on the **Tools** menu, choose **Visual Studio Command Prompt**. In the Visual Studio Command Prompt window, navigate to the folder that has the solution file, Umdf2toaster.sln. Use the MSBuild command to build the solution. Here is an example:
+
+**msbuild /p:configuration=”Win8 Release” /p:platform=”Win32” Umdf2toaster.sln**
+
+For more information about using MSBuild to build a driver package, see [Building a Driver](http://msdn.microsoft.com/en-us/library/windows/hardware/ff554644).
+
diff --git a/general/toaster/umdf2/exe/enum/Enum.vcxproj b/general/toaster/umdf2/exe/enum/Enum.vcxproj
new file mode 100644
index 00000000..822a36c7
--- /dev/null
+++ b/general/toaster/umdf2/exe/enum/Enum.vcxproj
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{2F2E0D4F-031E-4B76-983A-ED7F18562A15}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>Enum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>Enum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>Enum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>Enum</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="enum.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/exe/enum/Enum.vcxproj.Filters b/general/toaster/umdf2/exe/enum/Enum.vcxproj.Filters
new file mode 100644
index 00000000..c84e1e9f
--- /dev/null
+++ b/general/toaster/umdf2/exe/enum/Enum.vcxproj.Filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{58C64BCB-5021-4790-BBB0-C1AB7A443B79}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{17570C2B-4A49-4EB7-9BC8-219A1CDD870D}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{B5B13117-98BA-4E65-833F-2DB49A70E1DF}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="enum.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/exe/enum/enum.c b/general/toaster/umdf2/exe/enum/enum.c
new file mode 100644
index 00000000..ac285115
--- /dev/null
+++ b/general/toaster/umdf2/exe/enum/enum.c
@@ -0,0 +1,317 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ Enum.c
+
+Abstract:
+ This application simulates the plugin, unplug or ejection
+ of devices.
+
+Environment:
+
+ usermode console application
+
+Revision History:
+
+ Eliyas Yakub Oct 14, 1998
+
+
+--*/
+
+#include <basetyps.h>
+#include <stdlib.h>
+#include <wtypes.h>
+#include <setupapi.h>
+#include <initguid.h>
+#include <stdio.h>
+#include <string.h>
+#include <winioctl.h>
+#include "public.h"
+#include <dontuse.h>
+
+//
+// Prototypes
+//
+
+BOOLEAN
+OpenBusInterface (
+ _In_ HDEVINFO HardwareDeviceInfo,
+ _In_ PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
+ );
+
+
+
+#define USAGE \
+"Usage: Enum [-p SerialNo] Plugs in a device. SerialNo must be greater than zero.\n\
+ [-u SerialNo or 0] Unplugs device(s) - specify 0 to unplug all \
+ the devices enumerated so far.\n\
+ [-e SerialNo or 0] Ejects device(s) - specify 0 to eject all \
+ the devices enumerated so far.\n"
+
+BOOLEAN bPlugIn, bUnplug, bEject;
+ULONG SerialNo;
+
+INT __cdecl
+main(
+ _In_ ULONG argc,
+ _In_reads_(argc) PCHAR argv[]
+ )
+{
+ HDEVINFO hardwareDeviceInfo;
+ SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
+
+ bPlugIn = bUnplug = bEject = FALSE;
+
+ if(argc <3) {
+ goto usage;
+ }
+
+ if(argv[1][0] == '-') {
+ if(tolower(argv[1][1]) == 'p') {
+ if(argv[2])
+ SerialNo = (USHORT)atol(argv[2]);
+ bPlugIn = TRUE;
+ }
+ else if(tolower(argv[1][1]) == 'u') {
+ if(argv[2])
+ SerialNo = (ULONG)atol(argv[2]);
+ bUnplug = TRUE;
+ }
+ else if(tolower(argv[1][1]) == 'e') {
+ if(argv[2])
+ SerialNo = (ULONG)atol(argv[2]);
+ bEject = TRUE;
+ }
+ else {
+ goto usage;
+ }
+ }
+ else
+ goto usage;
+
+ if(bPlugIn && 0 == SerialNo)
+ goto usage;
+ //
+ // Open a handle to the device interface information set of all
+ // present toaster bus enumerator interfaces.
+ //
+
+ hardwareDeviceInfo = SetupDiGetClassDevs (
+ (LPGUID)&GUID_DEVINTERFACE_BUSENUM_TOASTER,
+ NULL, // Define no enumerator (global)
+ NULL, // Define no
+ (DIGCF_PRESENT | // Only Devices present
+ DIGCF_DEVICEINTERFACE)); // Function class devices.
+
+ if(INVALID_HANDLE_VALUE == hardwareDeviceInfo)
+ {
+ printf("SetupDiGetClassDevs failed: %x\n", GetLastError());
+ return 0;
+ }
+
+ deviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
+
+ if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
+ 0, // No care about specific PDOs
+ (LPGUID)&GUID_DEVINTERFACE_BUSENUM_TOASTER,
+ 0, //
+ &deviceInterfaceData)) {
+
+ OpenBusInterface(hardwareDeviceInfo, &deviceInterfaceData);
+ } else if (ERROR_NO_MORE_ITEMS == GetLastError()) {
+
+ printf(
+ "Error:Interface GUID_DEVINTERFACE_BUSENUM_TOASTER is not registered\n");
+ }
+
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+ return 0;
+usage:
+ printf(USAGE);
+ exit(0);
+}
+
+BOOLEAN
+OpenBusInterface (
+ _In_ HDEVINFO HardwareDeviceInfo,
+ _In_ PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData
+ )
+{
+ HANDLE file;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
+ ULONG predictedLength = 0;
+ ULONG requiredLength = 0;
+ ULONG bytes;
+ BUSENUM_UNPLUG_HARDWARE unplug;
+ BUSENUM_EJECT_HARDWARE eject;
+ PBUSENUM_PLUGIN_HARDWARE hardware;
+ BOOLEAN bSuccess;
+
+ //
+ // Allocate a function class device data structure to receive the
+ // information about this particular device.
+ //
+
+ SetupDiGetDeviceInterfaceDetail (
+ HardwareDeviceInfo,
+ DeviceInterfaceData,
+ NULL, // probing so no output buffer yet
+ 0, // probing so output buffer length of zero
+ &requiredLength,
+ NULL); // not interested in the specific dev-node
+
+ if(ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
+ printf("Error in SetupDiGetDeviceInterfaceDetail%d\n",
+ GetLastError());
+ return FALSE;
+ }
+
+ predictedLength = requiredLength;
+
+ deviceInterfaceDetailData = malloc (predictedLength);
+
+ if(deviceInterfaceDetailData) {
+ deviceInterfaceDetailData->cbSize =
+ sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
+ } else {
+ printf("Couldn't allocate %d bytes for device interface details.\n", predictedLength);
+ return FALSE;
+ }
+
+
+ if (! SetupDiGetDeviceInterfaceDetail (
+ HardwareDeviceInfo,
+ DeviceInterfaceData,
+ deviceInterfaceDetailData,
+ predictedLength,
+ &requiredLength,
+ NULL)) {
+ printf("Error in SetupDiGetDeviceInterfaceDetail\n");
+ free (deviceInterfaceDetailData);
+ return FALSE;
+ }
+
+ printf("Opening %s\n", deviceInterfaceDetailData->DevicePath);
+
+ file = CreateFile ( deviceInterfaceDetailData->DevicePath,
+ GENERIC_READ, // Only read access
+ 0, // FILE_SHARE_READ | FILE_SHARE_WRITE
+ NULL, // no SECURITY_ATTRIBUTES structure
+ OPEN_EXISTING, // No special create flags
+ 0, // No special attributes
+ NULL); // No template file
+
+ if (INVALID_HANDLE_VALUE == file) {
+ printf("CreateFile failed: 0x%x", GetLastError());
+ free (deviceInterfaceDetailData);
+ return FALSE;
+ }
+
+ printf("Bus interface opened!!!\n");
+
+ //
+ // From this point on, we need to jump to the end of the routine for
+ // common clean-up. Keep track of whether we succeeded or failed, so
+ // we'll know what to return to the caller.
+ //
+ bSuccess = FALSE;
+
+ //
+ // Enumerate Devices
+ //
+
+ if(bPlugIn) {
+
+ printf("SerialNo. of the device to be enumerated: %d\n", SerialNo);
+
+ hardware = malloc (bytes = (sizeof (BUSENUM_PLUGIN_HARDWARE) +
+ BUS_HARDWARE_IDS_LENGTH));
+
+ if(hardware) {
+ hardware->Size = sizeof (BUSENUM_PLUGIN_HARDWARE);
+ hardware->SerialNo = SerialNo;
+ } else {
+ printf("Couldn't allocate %d bytes for busenum plugin hardware structure.\n", bytes);
+ goto End;
+ }
+
+ //
+ // Allocate storage for the Device ID
+ //
+
+ memcpy (hardware->HardwareIDs,
+ BUS_HARDWARE_IDS,
+ BUS_HARDWARE_IDS_LENGTH);
+
+ if (!DeviceIoControl (file,
+ IOCTL_BUSENUM_PLUGIN_HARDWARE ,
+ hardware, bytes,
+ NULL, 0,
+ &bytes, NULL)) {
+ free (hardware);
+ printf("PlugIn failed:0x%x\n", GetLastError());
+ goto End;
+ }
+
+ free (hardware);
+ }
+
+ //
+ // Removes a device if given the specific Id of the device. Otherwise this
+ // ioctls removes all the devices that are enumerated so far.
+ //
+
+ if(bUnplug) {
+ printf("Unplugging device(s)....\n");
+
+ unplug.Size = bytes = sizeof (unplug);
+ unplug.SerialNo = SerialNo;
+ if (!DeviceIoControl (file,
+ IOCTL_BUSENUM_UNPLUG_HARDWARE,
+ &unplug, bytes,
+ NULL, 0,
+ &bytes, NULL)) {
+ printf("Unplug failed: 0x%x\n", GetLastError());
+ goto End;
+ }
+ }
+
+ //
+ // Ejects a device if given the specific Id of the device. Otherwise this
+ // ioctls ejects all the devices that are enumerated so far.
+ //
+
+ if(bEject)
+ {
+ printf("Ejecting Device(s)\n");
+
+ eject.Size = bytes = sizeof (eject);
+ eject.SerialNo = SerialNo;
+ if (!DeviceIoControl (file,
+ IOCTL_BUSENUM_EJECT_HARDWARE,
+ &eject, bytes,
+ NULL, 0,
+ &bytes, NULL)) {
+ printf("Eject failed: 0x%x\n", GetLastError());
+ goto End;
+ }
+ }
+
+ printf("Success!!!\n");
+ bSuccess = TRUE;
+
+End:
+ CloseHandle(file);
+ free (deviceInterfaceDetailData);
+ return bSuccess;
+}
+
+
diff --git a/general/toaster/umdf2/exe/notify/notify.c b/general/toaster/umdf2/exe/notify/notify.c
new file mode 100644
index 00000000..3362ce3d
--- /dev/null
+++ b/general/toaster/umdf2/exe/notify/notify.c
@@ -0,0 +1,1244 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name: notify.c
+
+
+Abstract:
+
+
+Author:
+
+ Eliyas Yakub Nov 23, 1999
+
+Environment:
+
+ User mode only.
+
+Revision History:
+
+ Modified to use linked list for deviceInfo
+ instead of arrays. (5/12/2000)
+
+--*/
+#define UNICODE
+#define _UNICODE
+#define INITGUID
+
+//
+// Annotation to indicate to prefast that this is nondriver user-mode code.
+//
+#include <DriverSpecs.h>
+_Analysis_mode_(_Analysis_code_type_user_code_)
+
+#include <windows.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setupapi.h>
+#include <dbt.h>
+#include <winioctl.h>
+#include <strsafe.h>
+#include "public.h"
+#include "notify.h"
+#include <dontuse.h>
+
+BOOL
+HandlePowerBroadcast(
+ HWND hWnd,
+ WPARAM wParam,
+ LPARAM lParam);
+
+//
+// Global variables
+//
+HINSTANCE hInst;
+HWND hWndList;
+TCHAR szTitle[]=TEXT("Toaster Package Test Application");
+LIST_ENTRY ListHead;
+HDEVNOTIFY hInterfaceNotification;
+TCHAR OutText[500];
+UINT ListBoxIndex = 0;
+GUID InterfaceGuid;// = GUID_DEVINTERFACE_TOASTER;
+BOOLEAN Verbose= FALSE;
+
+_inline BOOLEAN
+IsValid(
+ ULONG No
+ )
+{
+ PLIST_ENTRY thisEntry;
+ PDEVICE_INFO deviceInfo;
+
+ if(0==(No)) return TRUE; //special case
+
+ for(thisEntry = ListHead.Flink; thisEntry != &ListHead;
+ thisEntry = thisEntry->Flink)
+ {
+ deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
+ if((No) == deviceInfo->SerialNo) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+VOID
+Display(
+ _In_ LPWSTR pstrFormat, // @parm A printf style format string
+ ... // @parm | ... | Variable paramters based on <p pstrFormat>
+ )
+{
+ HRESULT hr;
+ va_list va;
+
+ va_start(va, pstrFormat);
+ //
+ // Truncation is acceptable.
+ //
+ hr = StringCbVPrintf(OutText, sizeof(OutText)-sizeof(WCHAR), pstrFormat, va);
+ va_end(va);
+
+ if(FAILED(hr)){
+ return;
+ }
+
+ SendMessage(hWndList, LB_INSERTSTRING, ListBoxIndex, (LPARAM)OutText);
+ SendMessage(hWndList, LB_SETCURSEL, ListBoxIndex, 0);
+ ListBoxIndex++;
+
+}
+
+VOID
+DisplayV(
+ _In_ LPWSTR pstrFormat, // @parm A printf style format string
+ ... // @parm | ... | Variable paramters based on <p pstrFormat>
+ )
+{
+ va_list va;
+
+ if (Verbose)
+ {
+ va_start(va, pstrFormat);
+ Display(pstrFormat, va);
+ va_end(va);
+ }
+}
+int PASCAL
+WinMain (
+ _In_ HINSTANCE hInstance,
+ _In_opt_ HINSTANCE hPrevInstance,
+ _In_ LPSTR lpCmdLine,
+ _In_ int nShowCmd
+ )
+{
+ static TCHAR szAppName[]=TEXT("Toaster Notify");
+ HWND hWnd;
+ MSG msg;
+ WNDCLASS wndclass;
+
+ UNREFERENCED_PARAMETER( lpCmdLine );
+
+ InterfaceGuid = GUID_DEVINTERFACE_TOASTER;
+ hInst=hInstance;
+
+ if (!hPrevInstance)
+ {
+ wndclass.style = CS_HREDRAW | CS_VREDRAW;
+ wndclass.lpfnWndProc = WndProc;
+ wndclass.cbClsExtra = 0;
+ wndclass.cbWndExtra = 0;
+ wndclass.hInstance = hInstance;
+ wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
+ wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
+ wndclass.hbrBackground= GetStockObject(WHITE_BRUSH);
+ wndclass.lpszMenuName = TEXT("GenericMenu");
+ wndclass.lpszClassName= szAppName;
+
+ RegisterClass(&wndclass);
+ }
+
+ hWnd = CreateWindow (szAppName,
+ szTitle,
+ WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ NULL,
+ NULL,
+ hInstance,
+ NULL);
+
+ ShowWindow (hWnd, nShowCmd);
+ UpdateWindow(hWnd);
+
+ while (GetMessage (&msg, NULL, 0,0))
+ {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+
+ return (0);
+}
+
+
+LRESULT
+FAR PASCAL
+WndProc (
+ HWND hWnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+ )
+{
+ DWORD nEventType = (DWORD)wParam;
+ PDEV_BROADCAST_HDR p = (PDEV_BROADCAST_HDR) lParam;
+ DEV_BROADCAST_DEVICEINTERFACE filter;
+
+ switch (message)
+ {
+
+ case WM_COMMAND:
+ HandleCommands(hWnd, message, wParam, lParam);
+ return 0;
+
+ case WM_CREATE:
+
+ //
+ // Load and set the icon of the program
+ //
+ SetClassLongPtr(hWnd, GCLP_HICON,
+ (LONG_PTR)LoadIcon((HINSTANCE)lParam,MAKEINTRESOURCE(IDI_CLASS_ICON)));
+
+ hWndList = CreateWindow (TEXT("listbox"),
+ NULL,
+ WS_CHILD|WS_VISIBLE|LBS_NOTIFY |
+ WS_VSCROLL | WS_BORDER,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ hWnd,
+ (HMENU)ID_EDIT,
+ hInst,
+ NULL);
+
+ filter.dbcc_size = sizeof(filter);
+ filter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
+ filter.dbcc_classguid = InterfaceGuid;
+ hInterfaceNotification = RegisterDeviceNotification(hWnd, &filter, 0);
+
+ InitializeListHead(&ListHead);
+ EnumExistingDevices(hWnd);
+
+ return 0;
+
+ case WM_SIZE:
+
+ MoveWindow(hWndList, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
+ return 0;
+
+ case WM_SETFOCUS:
+ SetFocus(hWndList);
+ return 0;
+
+ case WM_DEVICECHANGE:
+
+ //
+ // The DBT_DEVNODES_CHANGED broadcast message is sent
+ // everytime a device is added or removed. This message
+ // is typically handled by Device Manager kind of apps,
+ // which uses it to refresh window whenever something changes.
+ // The lParam is always NULL in this case.
+ //
+ if(DBT_DEVNODES_CHANGED == wParam) {
+ DisplayV(TEXT("Received DBT_DEVNODES_CHANGED broadcast message"));
+ return 0;
+ }
+
+ //
+ // All the events we're interested in come with lParam pointing to
+ // a structure headed by a DEV_BROADCAST_HDR. This is denoted by
+ // bit 15 of wParam being set, and bit 14 being clear.
+ //
+ if((wParam & 0xC000) == 0x8000) {
+
+ if (!p)
+ return 0;
+
+ if (p->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
+
+ HandleDeviceInterfaceChange(hWnd, nEventType, (PDEV_BROADCAST_DEVICEINTERFACE) p);
+ } else if (p->dbch_devicetype == DBT_DEVTYP_HANDLE) {
+
+ HandleDeviceChange(hWnd, nEventType, (PDEV_BROADCAST_HANDLE) p);
+ }
+ }
+ return 0;
+
+ case WM_POWERBROADCAST:
+ HandlePowerBroadcast(hWnd, wParam, lParam);
+ return 0;
+
+ case WM_CLOSE:
+ Cleanup(hWnd);
+ UnregisterDeviceNotification(hInterfaceNotification);
+ return DefWindowProc(hWnd,message, wParam, lParam);
+
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ return 0;
+ }
+ return DefWindowProc(hWnd,message, wParam, lParam);
+ }
+
+
+LRESULT
+HandleCommands(
+ HWND hWnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+ )
+
+{
+ PDIALOG_RESULT result = NULL;
+
+ UNREFERENCED_PARAMETER( uMsg );
+ UNREFERENCED_PARAMETER( lParam );
+
+ switch (wParam) {
+
+ case IDM_OPEN:
+ Cleanup(hWnd); // close all open handles
+ EnumExistingDevices(hWnd);
+ break;
+
+ case IDM_CLOSE:
+ Cleanup(hWnd);
+ break;
+
+ case IDM_HIDE:
+ result = (PDIALOG_RESULT)DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
+ if(result && result->SerialNo && IsValid(result->SerialNo)) {
+ DWORD bytes;
+ PDEVICE_INFO deviceInfo = NULL;
+ PLIST_ENTRY thisEntry;
+
+ //
+ // Find out the deviceInfo that matches this SerialNo.
+ // We need the deviceInfo to get the handle to the device.
+ //
+ for(thisEntry = ListHead.Flink; thisEntry != &ListHead;
+ thisEntry = thisEntry->Flink)
+ {
+ deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
+ if(result->SerialNo == deviceInfo->SerialNo) {
+ break;
+ }
+ deviceInfo = NULL;
+ }
+
+ //
+ // If found send I/O control
+ //
+
+ if (deviceInfo && !DeviceIoControl (deviceInfo->hDevice,
+ IOCTL_TOASTER_DONT_DISPLAY_IN_UI_DEVICE,
+ NULL, 0,
+ NULL, 0,
+ &bytes, NULL)) {
+ MessageBox(hWnd, TEXT("Request Failed or Invalid Serial No"),
+ TEXT("Error"), MB_OK);
+ }
+ }
+ break;
+ case IDM_PLUGIN:
+
+ result = (PDIALOG_RESULT)DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG), hWnd, DlgProc);
+ if(result) {
+ if(!result->SerialNo || !OpenBusInterface(result->SerialNo, result->DeviceId, PLUGIN)){
+ MessageBox(hWnd, TEXT("Invalid Serial Number or OpenBusInterface Failed"), TEXT("Error"), MB_OK);
+ }
+ }
+ break;
+ case IDM_UNPLUG:
+ result = (PDIALOG_RESULT)DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
+
+ if(result && IsValid(result->SerialNo)) {
+ if(!OpenBusInterface(result->SerialNo, NULL, UNPLUG)) {
+ MessageBox(hWnd, TEXT("Invalid Serial Number or OpenBusInterface Failed"), TEXT("Error"), MB_OK);
+ }
+ }
+ break;
+ case IDM_EJECT:
+ result = (PDIALOG_RESULT)DialogBox(hInst, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, DlgProc);
+ if(result && IsValid(result->SerialNo)) {
+ if(!OpenBusInterface(result->SerialNo, NULL, EJECT)) {
+ MessageBox(hWnd, TEXT("Invalid Serial Number or OpenBusInterface Failed"), TEXT("Error"), MB_OK);
+ }
+ }
+ break;
+
+ case IDM_CLEAR:
+ SendMessage(hWndList, LB_RESETCONTENT, 0, 0);
+ ListBoxIndex = 0;
+ break;
+
+ case IDM_IOCTL:
+ SendIoctlToFilterDevice();
+ break;
+
+ case IDM_VERBOSE: {
+
+ HMENU hMenu = GetMenu(hWnd);
+ Verbose = !Verbose;
+ if(Verbose) {
+ CheckMenuItem(hMenu, (UINT)wParam, MF_CHECKED);
+ } else {
+ CheckMenuItem(hMenu, (UINT)wParam, MF_UNCHECKED);
+ }
+ }
+ break;
+
+ case IDM_EXIT:
+ PostQuitMessage(0);
+ break;
+
+ default:
+ break;
+ }
+
+ if(result) {
+ HeapFree (GetProcessHeap(), 0, result);
+ }
+ return TRUE;
+}
+
+INT_PTR CALLBACK
+DlgProc(
+ HWND hDlg,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+)
+{
+ BOOL success;
+ PDIALOG_RESULT dialogResult = NULL;
+
+ UNREFERENCED_PARAMETER( lParam );
+
+ switch(message)
+ {
+ case WM_INITDIALOG:
+ SetDlgItemText(hDlg, IDC_DEVICEID, BUS_HARDWARE_IDS);
+ return TRUE;
+
+ case WM_COMMAND:
+ switch( wParam)
+ {
+ case ID_OK:
+ dialogResult = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ (sizeof(DIALOG_RESULT) + MAX_PATH * sizeof(WCHAR)));
+ if(dialogResult) {
+ dialogResult->DeviceId = (PWCHAR)((PCHAR)dialogResult + sizeof(DIALOG_RESULT));
+ dialogResult->SerialNo = GetDlgItemInt(hDlg,IDC_SERIALNO, &success, FALSE );
+ GetDlgItemText(hDlg, IDC_DEVICEID, dialogResult->DeviceId, MAX_PATH-1 );
+ }
+ EndDialog(hDlg, (UINT_PTR)dialogResult);
+ return TRUE;
+ case ID_CANCEL:
+ EndDialog(hDlg, 0);
+ return TRUE;
+
+ }
+ break;
+
+ }
+ return FALSE;
+}
+
+
+BOOL
+HandleDeviceInterfaceChange(
+ HWND hWnd,
+ DWORD evtype,
+ PDEV_BROADCAST_DEVICEINTERFACE dip
+ )
+{
+ DEV_BROADCAST_HANDLE filter;
+ PDEVICE_INFO deviceInfo = NULL;
+ HRESULT hr;
+
+ switch (evtype)
+ {
+ case DBT_DEVICEARRIVAL:
+ //
+ // New device arrived. Open handle to the device
+ // and register notification of type DBT_DEVTYP_HANDLE
+ //
+
+ deviceInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DEVICE_INFO));
+ if(!deviceInfo)
+ return FALSE;
+
+ InitializeListHead(&deviceInfo->ListEntry);
+ InsertTailList(&ListHead, &deviceInfo->ListEntry);
+
+
+ if(!GetDeviceDescription(dip->dbcc_name,
+ (PBYTE)deviceInfo->DeviceName,
+ sizeof(deviceInfo->DeviceName),
+ &deviceInfo->SerialNo)) {
+ MessageBox(hWnd, TEXT("GetDeviceDescription failed"), TEXT("Error!"), MB_OK);
+ }
+
+ Display(TEXT("New device Arrived (Interface Change Notification): %ws"),
+ deviceInfo->DeviceName);
+
+ hr = StringCchCopy(deviceInfo->DevicePath, MAX_PATH, dip->dbcc_name);
+ if(FAILED(hr)){
+ // DeviceInfo will be freed later by the cleanup routine.
+ break;
+ }
+
+ deviceInfo->hDevice = CreateFile(dip->dbcc_name,
+ GENERIC_READ |GENERIC_WRITE, 0, NULL,
+ OPEN_EXISTING, 0, NULL);
+ if(deviceInfo->hDevice == INVALID_HANDLE_VALUE) {
+ Display(TEXT("Failed to open the device: %ws"), deviceInfo->DeviceName);
+ break;
+ }
+
+ Display(TEXT("Opened handled to the device: %ws"), deviceInfo->DeviceName);
+ memset (&filter, 0, sizeof(filter)); //zero the structure
+ filter.dbch_size = sizeof(filter);
+ filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
+ filter.dbch_handle = deviceInfo->hDevice;
+
+ deviceInfo->hHandleNotification =
+ RegisterDeviceNotification(hWnd, &filter, 0);
+ break;
+
+ case DBT_DEVICEREMOVECOMPLETE:
+ Display(TEXT("Remove Complete (Interface Change Notification)"));
+ break;
+
+ //
+ // Device Removed.
+ //
+
+ default:
+ Display(TEXT("Unknown (Interface Change Notification)"));
+ break;
+ }
+ return TRUE;
+}
+
+BOOL
+HandleDeviceChange(
+ HWND hWnd,
+ DWORD evtype,
+ PDEV_BROADCAST_HANDLE dhp
+ )
+{
+ DEV_BROADCAST_HANDLE filter;
+ PDEVICE_INFO deviceInfo = NULL;
+ PLIST_ENTRY thisEntry;
+
+ //
+ // Walk the list to get the deviceInfo for this device
+ // by matching the handle given in the notification.
+ //
+ for(thisEntry = ListHead.Flink; thisEntry != &ListHead;
+ thisEntry = thisEntry->Flink)
+ {
+ deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
+ if(dhp->dbch_hdevnotify == deviceInfo->hHandleNotification) {
+ break;
+ }
+ deviceInfo = NULL;
+ }
+
+ if(!deviceInfo) {
+ Display(TEXT("Error: spurious message, Event Type %x, Device Type %x"),
+ evtype, dhp->dbch_devicetype);
+ return FALSE;
+ }
+
+ switch (evtype)
+ {
+
+ case DBT_DEVICEQUERYREMOVE:
+
+ Display(TEXT("Query Remove (Handle Notification)"), deviceInfo->DeviceName);
+
+ // User is trying to disable, uninstall, or eject our device.
+ // Close the handle to the device so that the target device can
+ // get removed. Do not unregister the notification
+ // at this point, because we want to know whether
+ // the device is successfully removed or not.
+ //
+ if (deviceInfo->hDevice != INVALID_HANDLE_VALUE) {
+
+ CloseHandle(deviceInfo->hDevice);
+ deviceInfo->hDevice = INVALID_HANDLE_VALUE;
+ Display(TEXT("Closed handle to device %ws"), deviceInfo->DeviceName );
+ }
+ break;
+
+ case DBT_DEVICEREMOVECOMPLETE:
+
+ Display(TEXT("Remove Complete (Handle Notification):%ws"),
+ deviceInfo->DeviceName);
+ //
+ // Device is getting surprise removed. So close
+ // the handle to device and unregister the PNP notification.
+ //
+
+ if (deviceInfo->hHandleNotification) {
+ UnregisterDeviceNotification(deviceInfo->hHandleNotification);
+ deviceInfo->hHandleNotification = NULL;
+ }
+ if (deviceInfo->hDevice != INVALID_HANDLE_VALUE) {
+
+ CloseHandle(deviceInfo->hDevice);
+ deviceInfo->hDevice = INVALID_HANDLE_VALUE;
+ Display(TEXT("Closed handle to device %ws"), deviceInfo->DeviceName );
+ }
+ //
+ // Unlink this deviceInfo from the list and free the memory
+ //
+ RemoveEntryList(&deviceInfo->ListEntry);
+ HeapFree (GetProcessHeap(), 0, deviceInfo);
+
+ break;
+
+ case DBT_DEVICEREMOVEPENDING:
+
+ Display(TEXT("Remove Pending (Handle Notification):%ws"),
+ deviceInfo->DeviceName);
+ //
+ // Device is successfully removed so unregister the notification
+ // and free the memory.
+ //
+ if (deviceInfo->hHandleNotification) {
+ UnregisterDeviceNotification(deviceInfo->hHandleNotification);
+ deviceInfo->hHandleNotification = NULL;
+ deviceInfo->hDevice = INVALID_HANDLE_VALUE;
+ }
+ //
+ // Unlink this deviceInfo from the list and free the memory
+ //
+ RemoveEntryList(&deviceInfo->ListEntry);
+ HeapFree (GetProcessHeap(), 0, deviceInfo);
+
+ break;
+
+ case DBT_DEVICEQUERYREMOVEFAILED :
+ Display(TEXT("Remove failed (Handle Notification):%ws"),
+ deviceInfo->DeviceName);
+ //
+ // Remove failed. So reopen the device and register for
+ // notification on the new handle. But first we should unregister
+ // the previous notification.
+ //
+ if (deviceInfo->hHandleNotification) {
+ UnregisterDeviceNotification(deviceInfo->hHandleNotification);
+ deviceInfo->hHandleNotification = NULL;
+ }
+ deviceInfo->hDevice = CreateFile(deviceInfo->DevicePath,
+ GENERIC_READ | GENERIC_WRITE,
+ 0, NULL, OPEN_EXISTING, 0, NULL);
+ if(deviceInfo->hDevice == INVALID_HANDLE_VALUE) {
+ Display(TEXT("Failed to reopen the device: %ws"),
+ deviceInfo->DeviceName);
+ HeapFree (GetProcessHeap(), 0, deviceInfo);
+ break;
+ }
+
+ //
+ // Register handle based notification to receive pnp
+ // device change notification on the handle.
+ //
+ memset (&filter, 0, sizeof(filter)); //zero the structure
+ filter.dbch_size = sizeof(filter);
+ filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
+ filter.dbch_handle = deviceInfo->hDevice;
+
+ deviceInfo->hHandleNotification =
+ RegisterDeviceNotification(hWnd, &filter, 0);
+ Display(TEXT("Reopened device %ws"), deviceInfo->DeviceName);
+ break;
+
+ default:
+ Display(TEXT("Unknown (Handle Notification)"), deviceInfo->DeviceName);
+ break;
+
+ }
+ return TRUE;
+}
+
+
+BOOLEAN
+EnumExistingDevices(
+ HWND hWnd
+)
+{
+ HDEVINFO hardwareDeviceInfo;
+ SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
+ ULONG predictedLength = 0;
+ ULONG requiredLength = 0;
+ DWORD error;
+ DEV_BROADCAST_HANDLE filter;
+ PDEVICE_INFO deviceInfo =NULL;
+ UINT i=0;
+ HRESULT hr;
+
+ hardwareDeviceInfo = SetupDiGetClassDevs (
+ (LPGUID)&InterfaceGuid,
+ NULL, // Define no enumerator (global)
+ NULL, // Define no
+ (DIGCF_PRESENT | // Only Devices present
+ DIGCF_DEVICEINTERFACE)); // Function class devices.
+ if(INVALID_HANDLE_VALUE == hardwareDeviceInfo)
+ {
+ goto Error;
+ }
+
+ //
+ // Enumerate devices of toaster class
+ //
+ deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
+
+ for(i=0; SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
+ 0, // No care about specific PDOs
+ (LPGUID)&InterfaceGuid,
+ i, //
+ &deviceInterfaceData); i++ ) {
+
+ //
+ // Allocate a function class device data structure to
+ // receive the information about this particular device.
+ //
+
+ //
+ // First find out required length of the buffer
+ //
+ if(deviceInterfaceDetailData)
+ {
+ HeapFree (GetProcessHeap(), 0, deviceInterfaceDetailData);
+ deviceInterfaceDetailData = NULL;
+ }
+
+ if(!SetupDiGetDeviceInterfaceDetail (
+ hardwareDeviceInfo,
+ &deviceInterfaceData,
+ NULL, // probing so no output buffer yet
+ 0, // probing so output buffer length of zero
+ &requiredLength,
+ NULL) && (error = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
+ {
+ goto Error;
+ }
+ predictedLength = requiredLength;
+
+ deviceInterfaceDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ predictedLength);
+ if (deviceInterfaceDetailData == NULL) {
+ goto Error;
+ }
+ deviceInterfaceDetailData->cbSize =
+ sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
+
+
+ if (! SetupDiGetDeviceInterfaceDetail (
+ hardwareDeviceInfo,
+ &deviceInterfaceData,
+ deviceInterfaceDetailData,
+ predictedLength,
+ &requiredLength,
+ NULL)) {
+ goto Error;
+ }
+
+ deviceInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ sizeof(DEVICE_INFO));
+ if (deviceInfo == NULL) {
+ goto Error;
+ }
+
+ InitializeListHead(&deviceInfo->ListEntry);
+ InsertTailList(&ListHead, &deviceInfo->ListEntry);
+
+ //
+ // Get the device details such as friendly name and SerialNo
+ //
+ if(!GetDeviceDescription(deviceInterfaceDetailData->DevicePath,
+ (PBYTE)deviceInfo->DeviceName,
+ sizeof(deviceInfo->DeviceName),
+ &deviceInfo->SerialNo)){
+ goto Error;
+ }
+
+ Display(TEXT("Found device %ws"), deviceInfo->DeviceName );
+
+ hr = StringCchCopy(deviceInfo->DevicePath, MAX_PATH, deviceInterfaceDetailData->DevicePath);
+ if(FAILED(hr)){
+ goto Error;
+ }
+ //
+ // Open an handle to the device.
+ //
+ deviceInfo->hDevice = CreateFile (
+ deviceInterfaceDetailData->DevicePath,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL, // no SECURITY_ATTRIBUTES structure
+ OPEN_EXISTING, // No special create flags
+ 0, // No special attributes
+ NULL);
+
+ if (INVALID_HANDLE_VALUE == deviceInfo->hDevice) {
+ Display(TEXT("Failed to open the device: %ws"), deviceInfo->DeviceName);
+ continue;
+ }
+
+ Display(TEXT("Opened handled to the device: %ws"), deviceInfo->DeviceName);
+ //
+ // Register handle based notification to receive pnp
+ // device change notification on the handle.
+ //
+
+ memset (&filter, 0, sizeof(filter)); //zero the structure
+ filter.dbch_size = sizeof(filter);
+ filter.dbch_devicetype = DBT_DEVTYP_HANDLE;
+ filter.dbch_handle = deviceInfo->hDevice;
+
+ deviceInfo->hHandleNotification = RegisterDeviceNotification(hWnd, &filter, 0);
+
+ }
+
+ if(deviceInterfaceDetailData)
+ HeapFree (GetProcessHeap(), 0, deviceInterfaceDetailData);
+
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+ return 0;
+
+Error:
+
+ MessageBox(hWnd, TEXT("EnumExisting Devices failed"), TEXT("Error!"), MB_OK);
+ if(deviceInterfaceDetailData)
+ HeapFree (GetProcessHeap(), 0, deviceInterfaceDetailData);
+
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+ Cleanup(hWnd);
+ return 0;
+}
+
+BOOLEAN Cleanup(HWND hWnd)
+{
+ PDEVICE_INFO deviceInfo =NULL;
+ PLIST_ENTRY thisEntry;
+
+ UNREFERENCED_PARAMETER( hWnd );
+
+ while (!IsListEmpty(&ListHead)) {
+ thisEntry = RemoveHeadList(&ListHead);
+ deviceInfo = CONTAINING_RECORD(thisEntry, DEVICE_INFO, ListEntry);
+ if (deviceInfo->hHandleNotification) {
+ UnregisterDeviceNotification(deviceInfo->hHandleNotification);
+ deviceInfo->hHandleNotification = NULL;
+ }
+ if (deviceInfo->hDevice != INVALID_HANDLE_VALUE &&
+ deviceInfo->hDevice != NULL) {
+ CloseHandle(deviceInfo->hDevice);
+ deviceInfo->hDevice = INVALID_HANDLE_VALUE;
+ Display(TEXT("Closed handle to device %ws"), deviceInfo->DeviceName );
+ }
+ HeapFree (GetProcessHeap(), 0, deviceInfo);
+ }
+ return TRUE;
+}
+
+
+BOOL
+GetDeviceDescription(
+ _In_ LPTSTR DevPath,
+ _Out_writes_bytes_(OutBufferLen) PBYTE OutBuffer,
+ _In_ ULONG OutBufferLen,
+ _In_ PULONG SerialNo
+)
+{
+ HDEVINFO hardwareDeviceInfo;
+ SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
+ SP_DEVINFO_DATA deviceInfoData;
+ DWORD dwRegType, error;
+
+ hardwareDeviceInfo = SetupDiCreateDeviceInfoList(NULL, NULL);
+ if(INVALID_HANDLE_VALUE == hardwareDeviceInfo)
+ {
+ goto Error;
+ }
+
+ //
+ // Enumerate devices of toaster class
+ //
+ deviceInterfaceData.cbSize = sizeof(deviceInterfaceData);
+
+ SetupDiOpenDeviceInterface (hardwareDeviceInfo, DevPath,
+ 0, //
+ &deviceInterfaceData);
+
+ deviceInfoData.cbSize = sizeof(deviceInfoData);
+ if(!SetupDiGetDeviceInterfaceDetail (
+ hardwareDeviceInfo,
+ &deviceInterfaceData,
+ NULL, // probing so no output buffer yet
+ 0, // probing so output buffer length of zero
+ NULL,
+ &deviceInfoData) && (error = GetLastError()) != ERROR_INSUFFICIENT_BUFFER)
+ {
+ goto Error;
+ }
+ //
+ // Get the friendly name for this instance, if that fails
+ // try to get the device description.
+ //
+
+ if(!SetupDiGetDeviceRegistryProperty(hardwareDeviceInfo, &deviceInfoData,
+ SPDRP_FRIENDLYNAME,
+ &dwRegType,
+ OutBuffer,
+ OutBufferLen,
+ NULL))
+ {
+ if(!SetupDiGetDeviceRegistryProperty(hardwareDeviceInfo, &deviceInfoData,
+ SPDRP_DEVICEDESC,
+ &dwRegType,
+ OutBuffer,
+ OutBufferLen,
+ NULL)){
+ goto Error;
+
+ }
+
+
+ }
+
+ //
+ // Get the serial number of the device. The bus driver reports
+ // the device serial number as UINumber in the devcaps.
+ //
+ if(!SetupDiGetDeviceRegistryProperty(hardwareDeviceInfo,
+ &deviceInfoData,
+ SPDRP_UI_NUMBER,
+ &dwRegType,
+ (BYTE*) SerialNo,
+ sizeof(ULONG),
+ NULL)) {
+ Display(TEXT("SerialNo is not available for device: %ws"), OutBuffer );
+ }
+
+
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+ return TRUE;
+
+Error:
+
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+ return FALSE;
+}
+
+
+
+BOOLEAN
+OpenBusInterface (
+ _In_ ULONG SerialNo,
+ _When_ (Action == PLUGIN, _In_) LPWSTR DeviceId,
+ _In_ USER_ACTION_TYPE Action
+ )
+{
+ HANDLE hDevice=INVALID_HANDLE_VALUE;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
+ ULONG predictedLength = 0;
+ ULONG requiredLength = 0;
+ ULONG bytes;
+ BUSENUM_UNPLUG_HARDWARE unplug;
+ BUSENUM_EJECT_HARDWARE eject;
+ PBUSENUM_PLUGIN_HARDWARE hardware;
+ HDEVINFO hardwareDeviceInfo;
+ SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
+ BOOLEAN status = FALSE;
+ HRESULT hr;
+ //
+ // Open a handle to the device interface information set of all
+ // present toaster bus enumerator interfaces.
+ //
+
+ hardwareDeviceInfo = SetupDiGetClassDevs (
+ (LPGUID)&GUID_DEVINTERFACE_BUSENUM_TOASTER,
+ NULL, // Define no enumerator (global)
+ NULL, // Define no
+ (DIGCF_PRESENT | // Only Devices present
+ DIGCF_DEVICEINTERFACE)); // Function class devices.
+
+ if(INVALID_HANDLE_VALUE == hardwareDeviceInfo)
+ {
+ return FALSE;
+ }
+
+ deviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
+
+ if (!SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
+ 0, // No care about specific PDOs
+ (LPGUID)&GUID_DEVINTERFACE_BUSENUM_TOASTER,
+ 0, //
+ &deviceInterfaceData)) {
+ goto Clean0;
+ }
+
+ //
+ // Allocate a function class device data structure to receive the
+ // information about this particular device.
+ //
+
+ SetupDiGetDeviceInterfaceDetail (
+ hardwareDeviceInfo,
+ &deviceInterfaceData,
+ NULL, // probing so no output buffer yet
+ 0, // probing so output buffer length of zero
+ &requiredLength,
+ NULL);//not interested in the specific dev-node
+
+ if(ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
+ goto Clean0;
+ }
+
+
+ predictedLength = requiredLength;
+
+ deviceInterfaceDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ predictedLength);
+
+ if(deviceInterfaceDetailData) {
+ deviceInterfaceDetailData->cbSize =
+ sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
+ } else {
+ goto Clean0;
+ }
+
+
+ if (! SetupDiGetDeviceInterfaceDetail (
+ hardwareDeviceInfo,
+ &deviceInterfaceData,
+ deviceInterfaceDetailData,
+ predictedLength,
+ &requiredLength,
+ NULL)) {
+ goto Clean1;
+ }
+
+
+ hDevice = CreateFile ( deviceInterfaceDetailData->DevicePath,
+ GENERIC_READ, // Only read access
+ 0, // FILE_SHARE_READ | FILE_SHARE_WRITE
+ NULL, // no SECURITY_ATTRIBUTES structure
+ OPEN_EXISTING, // No special create flags
+ 0, // No special attributes
+ NULL); // No template file
+
+ if (INVALID_HANDLE_VALUE == hDevice) {
+ goto Clean1;
+ }
+
+ //
+ // Enumerate Devices
+ //
+
+ if(Action == PLUGIN) {
+ int length = (int) (wcslen(DeviceId)+2)*sizeof(WCHAR); //in bytes
+
+ bytes = sizeof (BUSENUM_PLUGIN_HARDWARE) + length;
+ hardware = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bytes);
+
+ if(hardware) {
+ memset(hardware, 0, bytes);
+ hardware->Size = sizeof (BUSENUM_PLUGIN_HARDWARE);
+ hardware->SerialNo = SerialNo;
+ } else {
+ goto Clean2;
+ }
+
+ //
+ // copy the Device ID
+ //
+ hr = StringCchCopy(hardware->HardwareIDs, length/sizeof(WCHAR), DeviceId);
+ if (SUCCEEDED(hr) && DeviceIoControl (hDevice,
+ IOCTL_BUSENUM_PLUGIN_HARDWARE ,
+ hardware, bytes,
+ NULL, 0,
+ &bytes, NULL)) {
+ status = TRUE;
+ }
+
+ HeapFree (GetProcessHeap(), 0, hardware);
+
+ }
+
+ //
+ // Removes a device if given the specific Id of the device. Otherwise this
+ // ioctls removes all the devices that are enumerated so far.
+ //
+
+ if(Action == UNPLUG) {
+
+ unplug.Size = bytes = sizeof (unplug);
+ unplug.SerialNo = SerialNo;
+ if (DeviceIoControl (hDevice,
+ IOCTL_BUSENUM_UNPLUG_HARDWARE,
+ &unplug, bytes,
+ NULL, 0,
+ &bytes, NULL)) {
+ status = TRUE;
+ }
+ }
+
+ //
+ // Ejects a device if given the specific Id of the device. Otherwise this
+ // ioctls ejects all the devices that are enumerated so far.
+ //
+
+ if(Action == EJECT)
+ {
+
+ eject.Size = bytes = sizeof (eject);
+ eject.SerialNo = SerialNo;
+ if (DeviceIoControl (hDevice,
+ IOCTL_BUSENUM_EJECT_HARDWARE,
+ &eject, bytes,
+ NULL, 0,
+ &bytes, NULL)) {
+ status = TRUE;
+ }
+ }
+
+Clean2:
+ CloseHandle(hDevice);
+Clean1:
+ HeapFree (GetProcessHeap(), 0, deviceInterfaceDetailData);
+Clean0:
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+ return status;
+}
+
+BOOL
+HandlePowerBroadcast(
+ HWND hWnd,
+ WPARAM wParam,
+ LPARAM lParam)
+{
+ BOOL fRet = TRUE;
+
+ UNREFERENCED_PARAMETER( hWnd );
+ UNREFERENCED_PARAMETER( lParam );
+
+ switch (wParam)
+ {
+ case PBT_APMQUERYSTANDBY:
+ DisplayV(TEXT("PBT_APMQUERYSTANDBY"));
+ break;
+ case PBT_APMQUERYSUSPEND:
+ DisplayV(TEXT("PBT_APMQUERYSUSPEND"));
+ break;
+ case PBT_APMSTANDBY :
+ DisplayV(TEXT("PBT_APMSTANDBY"));
+ break;
+ case PBT_APMSUSPEND :
+ DisplayV(TEXT("PBT_APMSUSPEND"));
+ break;
+ case PBT_APMQUERYSTANDBYFAILED:
+ DisplayV(TEXT("PBT_APMQUERYSTANDBYFAILED"));
+ break;
+ case PBT_APMRESUMESTANDBY:
+ DisplayV(TEXT("PBT_APMRESUMESTANDBY"));
+ break;
+ case PBT_APMQUERYSUSPENDFAILED:
+ DisplayV(TEXT("PBT_APMQUERYSUSPENDFAILED"));
+ break;
+ case PBT_APMRESUMESUSPEND:
+ DisplayV(TEXT("PBT_APMRESUMESUSPEND"));
+ break;
+ case PBT_APMBATTERYLOW:
+ DisplayV(TEXT("PBT_APMBATTERYLOW"));
+ break;
+ case PBT_APMOEMEVENT:
+ DisplayV(TEXT("PBT_APMOEMEVENT"));
+ break;
+ case PBT_APMRESUMEAUTOMATIC:
+ DisplayV(TEXT("PBT_APMRESUMEAUTOMATIC"));
+ break;
+ case PBT_APMRESUMECRITICAL:
+ DisplayV(TEXT("PBT_APMRESUMECRITICAL"));
+ break;
+ case PBT_APMPOWERSTATUSCHANGE:
+ DisplayV(TEXT("PBT_APMPOWERSTATUSCHANGE"));
+ break;
+ default:
+ DisplayV(TEXT("Default"));
+ break;
+ }
+ return fRet;
+}
+
+void
+SendIoctlToFilterDevice()
+{
+#define IOCTL_CUSTOM_CODE CTL_CODE(FILE_DEVICE_UNKNOWN, 0, METHOD_BUFFERED, FILE_READ_DATA)
+
+ HANDLE hControlDevice;
+ ULONG bytes;
+
+ //
+ // Open handle to the control device. Please note that even
+ // a non-admin user can open handle to the device with
+ // FILE_READ_ATTRIBUTES | SYNCHRONIZE DesiredAccess and send IOCTLs if the
+ // IOCTL is defined with FILE_ANY_ACCESS. So for better security avoid
+ // specifying FILE_ANY_ACCESS in your IOCTL defintions.
+ // If the IOCTL is defined to have FILE_READ_DATA access rights, you can
+ // open the device with GENERIC_READ and call DeviceIoControl.
+ // If the IOCTL is defined to have FILE_WRITE_DATA access rights, you can
+ // open the device with GENERIC_WRITE and call DeviceIoControl.
+ //
+ hControlDevice = CreateFile ( TEXT("\\\\.\\ToasterFilter"),
+ GENERIC_READ, // Only read access
+ 0, // FILE_SHARE_READ | FILE_SHARE_WRITE
+ NULL, // no SECURITY_ATTRIBUTES structure
+ OPEN_EXISTING, // No special create flags
+ 0, // No special attributes
+ NULL); // No template file
+
+ if (INVALID_HANDLE_VALUE == hControlDevice) {
+ Display(TEXT("Failed to open ToasterFilter device"));
+ } else {
+ if (!DeviceIoControl (hControlDevice,
+ IOCTL_CUSTOM_CODE,
+ NULL, 0,
+ NULL, 0,
+ &bytes, NULL)) {
+ Display(TEXT("Ioctl to ToasterFilter device failed"));
+ } else {
+ Display(TEXT("Ioctl to ToasterFilter device succeeded"));
+ }
+ CloseHandle(hControlDevice);
+ }
+ return;
+}
diff --git a/general/toaster/umdf2/exe/notify/notify.h b/general/toaster/umdf2/exe/notify/notify.h
new file mode 100644
index 00000000..98db2918
--- /dev/null
+++ b/general/toaster/umdf2/exe/notify/notify.h
@@ -0,0 +1,182 @@
+/*++
+Copyright (c) 1990-2000 Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ notify.h
+
+Abstract:
+
+
+Author:
+
+ Eliyas Yakub Nov 23, 1999
+
+Environment:
+
+
+Revision History:
+
+
+--*/
+
+#ifndef __NOTIFY_H
+#define __NOTIFY_H
+
+
+//
+// Copied Macros from ntddk.h
+//
+
+#define CONTAINING_RECORD(address, type, field) ((type *)( \
+ (PCHAR)(address) - \
+ (ULONG_PTR)(&((type *)0)->field)))
+
+
+#define InitializeListHead(ListHead) (\
+ (ListHead)->Flink = (ListHead)->Blink = (ListHead))
+
+#define RemoveHeadList(ListHead) \
+ (ListHead)->Flink;\
+ {RemoveEntryList((ListHead)->Flink)}
+
+#define IsListEmpty(ListHead) \
+ ((ListHead)->Flink == (ListHead))
+
+
+#define RemoveEntryList(Entry) {\
+ PLIST_ENTRY _EX_Blink;\
+ PLIST_ENTRY _EX_Flink;\
+ _EX_Flink = (Entry)->Flink;\
+ _EX_Blink = (Entry)->Blink;\
+ _EX_Blink->Flink = _EX_Flink;\
+ _EX_Flink->Blink = _EX_Blink;\
+ }
+
+#define InsertTailList(ListHead,Entry) {\
+ PLIST_ENTRY _EX_Blink;\
+ PLIST_ENTRY _EX_ListHead;\
+ _EX_ListHead = (ListHead);\
+ _EX_Blink = _EX_ListHead->Blink;\
+ (Entry)->Flink = _EX_ListHead;\
+ (Entry)->Blink = _EX_Blink;\
+ _EX_Blink->Flink = (Entry);\
+ _EX_ListHead->Blink = (Entry);\
+ }
+
+typedef struct _DEVICE_INFO
+{
+ HANDLE hDevice; // file handle
+ HDEVNOTIFY hHandleNotification; // notification handle
+ TCHAR DeviceName[MAX_PATH];// friendly name of device description
+ TCHAR DevicePath[MAX_PATH];//
+ ULONG SerialNo; // Serial number of the device.
+ LIST_ENTRY ListEntry;
+} DEVICE_INFO, *PDEVICE_INFO;
+
+
+typedef enum {
+
+ PLUGIN = 1,
+ UNPLUG,
+ EJECT
+
+} USER_ACTION_TYPE;
+
+typedef struct _DIALOG_RESULT
+{
+ ULONG SerialNo;
+ PWCHAR DeviceId;
+} DIALOG_RESULT, *PDIALOG_RESULT;
+
+#define ID_EDIT 1
+
+#define IDM_OPEN 100
+#define IDM_CLOSE 101
+#define IDM_EXIT 102
+#define IDM_HIDE 103
+#define IDM_PLUGIN 104
+#define IDM_UNPLUG 105
+#define IDM_EJECT 106
+#define IDM_ENABLE 107
+#define IDM_DISABLE 108
+#define IDM_CLEAR 109
+#define IDM_IOCTL 110
+#define IDM_VERBOSE 111
+
+#define IDD_DIALOG 115
+#define IDD_DIALOG1 116
+#define IDD_DIALOG2 117
+#define ID_OK 118
+#define ID_CANCEL 119
+#define IDC_SERIALNO 1000
+#define IDC_DEVICEID 1001
+#define IDC_STATIC -1
+
+#define IDI_CLASS_ICON 200
+
+LRESULT FAR PASCAL
+WndProc (
+ HWND hwnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam
+ );
+
+BOOLEAN EnumExistingDevices(
+ HWND hWnd
+ );
+
+BOOL HandleDeviceInterfaceChange(
+ HWND hwnd,
+ DWORD evtype,
+ PDEV_BROADCAST_DEVICEINTERFACE dip
+ );
+
+BOOL HandleDeviceChange(
+ HWND hwnd,
+ DWORD evtype,
+ PDEV_BROADCAST_HANDLE dhp
+ );
+
+LRESULT
+HandleCommands(
+ HWND hWnd,
+ UINT uMsg,
+ WPARAM wParam,
+ LPARAM lParam
+ );
+
+BOOLEAN Cleanup(
+ HWND hWnd
+ );
+
+BOOL
+GetDeviceDescription(
+ _In_ LPTSTR DevPath,
+ _Out_writes_bytes_(OutBufferLen) PBYTE OutBuffer,
+ _In_ ULONG OutBufferLen,
+ _In_ PULONG SerialNo
+ );
+
+BOOLEAN
+OpenBusInterface (
+ _In_ ULONG SerialNo,
+ _When_ (Action == PLUGIN, _In_) LPWSTR DeviceId,
+ _In_ USER_ACTION_TYPE Action
+ );
+
+
+INT_PTR CALLBACK
+DlgProc(
+ HWND hDlg,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam);
+
+void
+SendIoctlToFilterDevice();
+
+
+#endif
+
diff --git a/general/toaster/umdf2/exe/notify/notify.rc b/general/toaster/umdf2/exe/notify/notify.rc
new file mode 100644
index 00000000..eb15657f
--- /dev/null
+++ b/general/toaster/umdf2/exe/notify/notify.rc
@@ -0,0 +1,77 @@
+#include "windows.h"
+
+#include "notify.h"
+
+
+GenericMenu MENU
+ {
+ POPUP "&File"
+ {
+ MENUITEM "Clear &Display", IDM_CLEAR
+ MENUITEM "&Verbose Trace", IDM_VERBOSE
+ MENUITEM "E&xit", IDM_EXIT
+ }
+ POPUP "&Bus"
+ {
+ MENUITEM "&PlugIn", IDM_PLUGIN
+ MENUITEM "&UnPlug (Surprise Removal)", IDM_UNPLUG
+ MENUITEM "&Eject", IDM_EJECT
+ }
+ POPUP "&Function"
+ {
+ MENUITEM "&Open", IDM_OPEN
+ MENUITEM "&Close", IDM_CLOSE
+ MENUITEM "&Hide", IDM_HIDE
+
+ }
+ POPUP "Fil&ter"
+ {
+ MENUITEM "&Ioctl to Control Device", IDM_IOCTL
+ }
+ }
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog for plug in
+//
+
+IDD_DIALOG DIALOG DISCARDABLE 0, 0, 289, 86
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Plug In Device"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ DEFPUSHBUTTON "OK",ID_OK,72,61,50,14,BS_NOTIFY
+ PUSHBUTTON "CANCEL",ID_CANCEL,170,60,50,14,BS_NOTIFY
+ LTEXT "Serial Number :",IDC_STATIC,18,13,55,8
+ LTEXT "Device ID :",IDC_STATIC,20,35,55,8
+ EDITTEXT IDC_SERIALNO,75,11,24,14,ES_NUMBER
+ EDITTEXT IDC_DEVICEID,76,32,200,14,ES_AUTOHSCROLL
+END
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog for unplug/hide/enable/disable
+//
+
+IDD_DIALOG1 DIALOG DISCARDABLE 0, 0, 232, 86
+STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
+CAPTION "Enter SerialNo of the device"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Serial Number :",IDC_STATIC,18,13,55,8
+ EDITTEXT IDC_SERIALNO,75,11,24,14,ES_NUMBER
+ DEFPUSHBUTTON "OK",ID_OK,27,61,50,14,BS_NOTIFY
+ PUSHBUTTON "CANCEL",ID_CANCEL,121,60,50,14,BS_NOTIFY
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Icon
+//
+
+IDI_CLASS_ICON ICON DISCARDABLE "TOASTER.ICO"
+
+
diff --git a/general/toaster/umdf2/exe/notify/notify.vcxproj b/general/toaster/umdf2/exe/notify/notify.vcxproj
new file mode 100644
index 00000000..9d65f2f7
--- /dev/null
+++ b/general/toaster/umdf2/exe/notify/notify.vcxproj
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{83E3E107-0EC1-44A8-BA29-BFBB6C43DC53}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>notify</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>notify</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>notify</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>notify</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="notify.c" />
+ <ResourceCompile Include="notify.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/exe/notify/notify.vcxproj.Filters b/general/toaster/umdf2/exe/notify/notify.vcxproj.Filters
new file mode 100644
index 00000000..ccccf66b
--- /dev/null
+++ b/general/toaster/umdf2/exe/notify/notify.vcxproj.Filters
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{26C90330-C836-4747-995F-76F38B79BDA9}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{04722C15-5D21-4294-B1A9-004CFAF38D17}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{600866EB-F078-4625-8B46-D93F60CD2380}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="notify.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="notify.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/exe/notify/toaster.ico b/general/toaster/umdf2/exe/notify/toaster.ico
new file mode 100644
index 00000000..77ad2081
--- /dev/null
+++ b/general/toaster/umdf2/exe/notify/toaster.ico
Binary files differ
diff --git a/general/toaster/umdf2/exe/toast/toast.c b/general/toaster/umdf2/exe/toast/toast.c
new file mode 100644
index 00000000..4f0525c6
--- /dev/null
+++ b/general/toaster/umdf2/exe/toast/toast.c
@@ -0,0 +1,343 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ TOAST.C
+
+Abstract:
+
+ Lists all the toaster device and interfaces present in the system
+ and opens the last interface to send an invalidate device Ioctl request
+ or read requests.
+
+Environment:
+
+ usermode console application
+
+Revision History:
+
+ Eliyas Yakub Nov 2, 1998
+
+
+--*/
+
+#include <basetyps.h>
+#include <stdlib.h>
+#include <wtypes.h>
+#include <setupapi.h>
+#include <initguid.h>
+#include <stdio.h>
+#include <string.h>
+#include <winioctl.h>
+#include "public.h"
+#include <conio.h>
+#include <dontuse.h>
+
+#define USAGE \
+"Usage: Toast <-h> {-h option causes the device to hide from Device Manager UI}\n"
+
+BOOL PrintToasterDeviceInfo();
+
+INT __cdecl
+main(
+ _In_ ULONG argc,
+ _In_reads_(argc) PCHAR argv[]
+ )
+{
+ HDEVINFO hardwareDeviceInfo;
+ SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData = NULL;
+ ULONG predictedLength = 0;
+ ULONG requiredLength = 0, bytes=0;
+ HANDLE file;
+ int i, ch;
+ char buffer[10];
+ BOOL bHide = FALSE;
+
+ if(argc == 2) {
+ if(argv[1][0] == '-') {
+ if(argv[1][1] == 'h' || argv[1][1] == 'H') {
+ bHide = TRUE;
+ } else {
+ printf(USAGE);
+ exit(0);
+ }
+ }
+ else {
+ printf(USAGE);
+ exit(0);
+ }
+ }
+
+
+ //
+ // Print a list of devices of Toaster Class
+ //
+ if(!PrintToasterDeviceInfo())
+ {
+ printf("No toaster devices present\n");
+ return 0;
+ }
+
+ //
+ // Open a handle to the device interface information set of all
+ // present toaster class interfaces.
+ //
+
+ hardwareDeviceInfo = SetupDiGetClassDevs (
+ (LPGUID)&GUID_DEVINTERFACE_TOASTER,
+ NULL, // Define no enumerator (global)
+ NULL, // Define no
+ (DIGCF_PRESENT | // Only Devices present
+ DIGCF_DEVICEINTERFACE)); // Function class devices.
+ if(INVALID_HANDLE_VALUE == hardwareDeviceInfo)
+ {
+ printf("SetupDiGetClassDevs failed: %x\n", GetLastError());
+ return 0;
+ }
+
+ deviceInterfaceData.cbSize = sizeof (SP_DEVICE_INTERFACE_DATA);
+
+ printf("\nList of Toaster Device Interfaces\n");
+ printf("---------------------------------\n");
+
+ i = 0;
+
+ //
+ // Enumerate devices of toaster class
+ //
+
+ for(;;) {
+ if (SetupDiEnumDeviceInterfaces (hardwareDeviceInfo,
+ 0, // No care about specific PDOs
+ (LPGUID)&GUID_DEVINTERFACE_TOASTER,
+ i, //
+ &deviceInterfaceData)) {
+
+ if(deviceInterfaceDetailData) {
+ free (deviceInterfaceDetailData);
+ deviceInterfaceDetailData = NULL;
+ }
+
+ //
+ // Allocate a function class device data structure to
+ // receive the information about this particular device.
+ //
+
+ //
+ // First find out required length of the buffer
+ //
+
+ if(!SetupDiGetDeviceInterfaceDetail (
+ hardwareDeviceInfo,
+ &deviceInterfaceData,
+ NULL, // probing so no output buffer yet
+ 0, // probing so output buffer length of zero
+ &requiredLength,
+ NULL)) { // not interested in the specific dev-node
+ if(ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
+ printf("SetupDiGetDeviceInterfaceDetail failed %d\n", GetLastError());
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+ return FALSE;
+ }
+
+ }
+
+ predictedLength = requiredLength;
+
+ deviceInterfaceDetailData = malloc (predictedLength);
+
+ if(deviceInterfaceDetailData) {
+ deviceInterfaceDetailData->cbSize =
+ sizeof (SP_DEVICE_INTERFACE_DETAIL_DATA);
+ } else {
+ printf("Couldn't allocate %d bytes for device interface details.\n", predictedLength);
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+ return FALSE;
+ }
+
+
+ if (! SetupDiGetDeviceInterfaceDetail (
+ hardwareDeviceInfo,
+ &deviceInterfaceData,
+ deviceInterfaceDetailData,
+ predictedLength,
+ &requiredLength,
+ NULL)) {
+ printf("Error in SetupDiGetDeviceInterfaceDetail\n");
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+ free (deviceInterfaceDetailData);
+ return FALSE;
+ }
+ printf("%d) %s\n", ++i,
+ deviceInterfaceDetailData->DevicePath);
+ }
+ else if (ERROR_NO_MORE_ITEMS != GetLastError()) {
+ free (deviceInterfaceDetailData);
+ deviceInterfaceDetailData = NULL;
+ continue;
+ }
+ else
+ break;
+
+ }
+
+
+ SetupDiDestroyDeviceInfoList (hardwareDeviceInfo);
+
+ if(!deviceInterfaceDetailData)
+ {
+ printf("No device interfaces present\n");
+ return 0;
+ }
+
+ //
+ // Open the last toaster device interface
+ //
+
+ printf("\nOpening the last interface:\n %s\n",
+ deviceInterfaceDetailData->DevicePath);
+
+ file = CreateFile ( deviceInterfaceDetailData->DevicePath,
+ GENERIC_READ | GENERIC_WRITE,
+ 0,
+ NULL, // no SECURITY_ATTRIBUTES structure
+ OPEN_EXISTING, // No special create flags
+ 0, // No special attributes
+ NULL);
+
+ if (INVALID_HANDLE_VALUE == file) {
+ printf("Error in CreateFile: %x", GetLastError());
+ free (deviceInterfaceDetailData);
+ return 0;
+ }
+
+ //
+ // Invalidate the Device State
+ //
+
+ if(bHide)
+ {
+ if (!DeviceIoControl (file,
+ IOCTL_TOASTER_DONT_DISPLAY_IN_UI_DEVICE,
+ NULL, 0,
+ NULL, 0,
+ &bytes, NULL)) {
+ printf("Invalidate device request failed:0x%x\n", GetLastError());
+ free (deviceInterfaceDetailData);
+ CloseHandle(file);
+ return 0;
+ }
+ printf("\nRequest to hide the device completed successfully\n");
+
+ }
+
+
+ //
+ // Read/Write to the toaster device.
+ //
+
+ printf("\nPress 'q' to exit, any other key to read...\n");
+ fflush(stdin);
+ ch = _getche();
+
+ while(tolower(ch) != 'q' )
+ {
+
+ if(!ReadFile(file, buffer, sizeof(buffer), &bytes, NULL))
+ {
+ printf("Error in ReadFile: %x", GetLastError());
+ break;
+ }
+ printf("Read Successful\n");
+ ch = _getche();
+ }
+
+ free (deviceInterfaceDetailData);
+ CloseHandle(file);
+ return 0;
+}
+
+
+
+BOOL
+PrintToasterDeviceInfo()
+{
+ HDEVINFO hdi;
+ DWORD dwIndex=0;
+ SP_DEVINFO_DATA deid;
+ BOOL fSuccess=FALSE;
+ CHAR szCompInstanceId[MAX_PATH];
+ CHAR szCompDescription[MAX_PATH];
+ CHAR szFriendlyName[MAX_PATH];
+ DWORD dwRegType;
+ BOOL fFound=FALSE;
+
+ // get a list of all devices of class 'GUID_DEVCLASS_TOASTER'
+ hdi = SetupDiGetClassDevs(&GUID_DEVCLASS_TOASTER, NULL, NULL,
+ DIGCF_PRESENT);
+
+ if (INVALID_HANDLE_VALUE != hdi)
+ {
+
+ // enumerate over each device
+ while (deid.cbSize = sizeof(SP_DEVINFO_DATA),
+ SetupDiEnumDeviceInfo(hdi, dwIndex, &deid))
+ {
+ dwIndex++;
+
+ // the right thing to do here would be to call this function
+ // to get the size required to hold the instance ID and then
+ // to call it second time with a buffer large enough for that size.
+ // However, that would tend to obscure the control flow in
+ // the sample code. Lets keep things simple by keeping the
+ // buffer large enough.
+
+ // get the device instance ID
+ fSuccess = SetupDiGetDeviceInstanceId(hdi, &deid,
+ szCompInstanceId,
+ MAX_PATH, NULL);
+ if (fSuccess)
+ {
+ // get the description for this instance
+ fSuccess =
+ SetupDiGetDeviceRegistryProperty(hdi, &deid,
+ SPDRP_DEVICEDESC,
+ &dwRegType,
+ (BYTE*) szCompDescription,
+ MAX_PATH,
+ NULL);
+ if (fSuccess)
+ {
+ memset(szFriendlyName, 0, MAX_PATH);
+ SetupDiGetDeviceRegistryProperty(hdi, &deid,
+ SPDRP_FRIENDLYNAME,
+ &dwRegType,
+ (BYTE*) szFriendlyName,
+ MAX_PATH,
+ NULL);
+ fFound = TRUE;
+ printf("Instance ID : %s\n", szCompInstanceId);
+ printf("Description : %s\n", szCompDescription);
+ printf("FriendlyName: %s\n\n", szFriendlyName);
+ }
+ }
+ }
+
+ // release the device info list
+ SetupDiDestroyDeviceInfoList(hdi);
+ }
+
+ if(fFound)
+ return TRUE;
+ else
+ return FALSE;
+}
+
diff --git a/general/toaster/umdf2/exe/toast/toast.vcxproj b/general/toaster/umdf2/exe/toast/toast.vcxproj
new file mode 100644
index 00000000..45a4ceb0
--- /dev/null
+++ b/general/toaster/umdf2/exe/toast/toast.vcxproj
@@ -0,0 +1,171 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{9BF4F988-D8B7-4E73-BC77-6658D413212F}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{5A95B864-3AA6-41E5-AF06-4FB9836D4219}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Desktop</DriverTargetPlatform>
+ <DriverType />
+ <PlatformToolset>WindowsApplicationForDrivers10.0</PlatformToolset>
+ <ConfigurationType>Application</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>toast</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>toast</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>toast</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>toast</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);setupapi.lib</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="toast.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/exe/toast/toast.vcxproj.Filters b/general/toaster/umdf2/exe/toast/toast.vcxproj.Filters
new file mode 100644
index 00000000..b418a4e3
--- /dev/null
+++ b/general/toaster/umdf2/exe/toast/toast.vcxproj.Filters
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{74122CFE-AC0A-405A-887C-C84F0A71602A}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{BF44B779-EC06-4E53-8DA1-5B27378BE11C}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{92FCEB4A-CD44-4D16-8B54-1B192FADB341}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="toast.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/filter/generic/filter.c b/general/toaster/umdf2/filter/generic/filter.c
new file mode 100644
index 00000000..d245c2ba
--- /dev/null
+++ b/general/toaster/umdf2/filter/generic/filter.c
@@ -0,0 +1,387 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ filter.c
+
+Abstract:
+
+ This module shows how to a write a generic filter driver. The driver demonstrates how
+ to support device I/O control requests through queues. All the I/O requests passed on to
+ the lower driver. This filter driver shows how to handle IRP postprocessing by forwarding
+ the requests with and without a completion routine. To forward with a completion routine
+ set the define FORWARD_REQUEST_WITH_COMPLETION to 1.
+
+Environment:
+
+ User mode
+
+--*/
+
+#include "filter.h"
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text (INIT, DriverEntry)
+#pragma alloc_text (PAGE, FilterEvtDeviceAdd)
+#endif
+
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+
+ Installable driver initialization entry point.
+ This entry point is called directly by the I/O system.
+
+Arguments:
+
+ DriverObject - pointer to the driver object
+
+ RegistryPath - pointer to a unicode string representing the path,
+ to driver-specific key in the registry.
+
+Return Value:
+
+ STATUS_SUCCESS if successful,
+ STATUS_UNSUCCESSFUL otherwise.
+
+--*/
+{
+ WDF_DRIVER_CONFIG config;
+ NTSTATUS status;
+ WDFDRIVER hDriver;
+
+ KdPrint(("Toaster Generic Filter Driver Sample - Driver Framework Edition.\n"));
+
+ //
+ // Initiialize driver config to control the attributes that
+ // are global to the driver. Note that framework by default
+ // provides a driver unload routine. If you create any resources
+ // in the DriverEntry and want to be cleaned in driver unload,
+ // you can override that by manually setting the EvtDriverUnload in the
+ // config structure. In general xxx_CONFIG_INIT macros are provided to
+ // initialize most commonly used members.
+ //
+
+ WDF_DRIVER_CONFIG_INIT(
+ &config,
+ FilterEvtDeviceAdd
+ );
+
+ //
+ // Create a framework driver object to represent our driver.
+ //
+ status = WdfDriverCreate(DriverObject,
+ RegistryPath,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &config,
+ &hDriver);
+ if (!NT_SUCCESS(status)) {
+ KdPrint( ("WdfDriverCreate failed with status 0x%x\n", status));
+ }
+
+ return status;
+}
+
+
+NTSTATUS
+FilterEvtDeviceAdd(
+ IN WDFDRIVER Driver,
+ IN PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+Routine Description:
+
+ EvtDeviceAdd is called by the framework in response to AddDevice
+ call from the PnP manager. Here you can query the device properties
+ using WdfFdoInitWdmGetPhysicalDevice/IoGetDeviceProperty and based
+ on that, decide to create a filter device object and attach to the
+ function stack. If you are not interested in filtering this particular
+ instance of the device, you can just return STATUS_SUCCESS without creating
+ a framework device.
+
+Arguments:
+
+ Driver - Handle to a framework driver object created in DriverEntry
+
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ WDF_OBJECT_ATTRIBUTES deviceAttributes;
+ PFILTER_EXTENSION filterExt;
+ NTSTATUS status;
+ WDFDEVICE device;
+ WDF_IO_QUEUE_CONFIG ioQueueConfig;
+
+ PAGED_CODE ();
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ //
+ // Tell the framework that you are filter driver. Framework
+ // takes care of inherting all the device flags & characterstics
+ // from the lower device you are attaching to.
+ //
+ WdfFdoInitSetFilter(DeviceInit);
+
+ //
+ // Specify the size of device extension where we track per device
+ // context.
+ //
+
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, FILTER_EXTENSION);
+
+ //
+ // Create a framework device object.This call will inturn create
+ // a WDM deviceobject, attach to the lower stack and set the
+ // appropriate flags and attributes.
+ //
+ status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device);
+ if (!NT_SUCCESS(status)) {
+ KdPrint( ("WdfDeviceCreate failed with status code 0x%x\n", status));
+ return status;
+ }
+
+ filterExt = FilterGetData(device);
+
+ //
+ // Configure the default queue to be Parallel.
+ //
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig,
+ WdfIoQueueDispatchParallel);
+
+ //
+ // Framework by default creates non-power managed queues for
+ // filter drivers.
+ //
+ ioQueueConfig.EvtIoDeviceControl = FilterEvtIoDeviceControl;
+
+ status = WdfIoQueueCreate(device,
+ &ioQueueConfig,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ WDF_NO_HANDLE // pointer to default queue
+ );
+ if (!NT_SUCCESS(status)) {
+ KdPrint( ("WdfIoQueueCreate failed 0x%x\n", status));
+ return status;
+ }
+
+ return status;
+}
+
+VOID
+FilterEvtIoDeviceControl(
+ IN WDFQUEUE Queue,
+ IN WDFREQUEST Request,
+ IN size_t OutputBufferLength,
+ IN size_t InputBufferLength,
+ IN ULONG IoControlCode
+ )
+/*++
+
+Routine Description:
+
+ This routine is the dispatch routine for internal device control requests.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated
+ with the I/O request.
+ Request - Handle to a framework request object.
+
+ OutputBufferLength - length of the request's output buffer,
+ if an output buffer is available.
+ InputBufferLength - length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - the driver-defined or system-defined I/O control code
+ (IOCTL) that is associated with the request.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ PFILTER_EXTENSION filterExt;
+ NTSTATUS status = STATUS_SUCCESS;
+ WDFDEVICE device;
+
+ UNREFERENCED_PARAMETER(OutputBufferLength);
+ UNREFERENCED_PARAMETER(InputBufferLength);
+
+ KdPrint(("Entered FilterEvtIoDeviceControl\n"));
+
+ device = WdfIoQueueGetDevice(Queue);
+
+ filterExt = FilterGetData(device);
+
+ switch (IoControlCode) {
+
+ //
+ // Put your cases for handling IOCTLs here
+ //
+
+ default:
+ status = STATUS_SUCCESS;
+ }
+
+ if (!NT_SUCCESS(status)) {
+ WdfRequestComplete(Request, status);
+ return;
+ }
+
+ //
+ // Forward the request down. WdfDeviceGetIoTarget returns
+ // the default target, which represents the device attached to us below in
+ // the stack.
+ //
+#if FORWARD_REQUEST_WITH_COMPLETION
+ //
+ // Use this routine to forward a request if you are interested in post
+ // processing the IRP.
+ //
+ FilterForwardRequestWithCompletionRoutine(Request,
+ WdfDeviceGetIoTarget(device));
+#else
+ FilterForwardRequest(Request, WdfDeviceGetIoTarget(device));
+#endif
+
+ return;
+}
+
+VOID
+FilterForwardRequest(
+ IN WDFREQUEST Request,
+ IN WDFIOTARGET Target
+ )
+/*++
+Routine Description:
+
+ Passes a request on to the lower driver.
+
+--*/
+{
+ WDF_REQUEST_SEND_OPTIONS options;
+ BOOLEAN ret;
+ NTSTATUS status;
+
+ //
+ // We are not interested in post processing the IRP so
+ // fire and forget.
+ //
+ WDF_REQUEST_SEND_OPTIONS_INIT(&options,
+ WDF_REQUEST_SEND_OPTION_SEND_AND_FORGET);
+
+ ret = WdfRequestSend(Request, Target, &options);
+
+ if (ret == FALSE) {
+ status = WdfRequestGetStatus (Request);
+ KdPrint( ("WdfRequestSend failed: 0x%x\n", status));
+ WdfRequestComplete(Request, status);
+ }
+
+ return;
+}
+
+#if FORWARD_REQUEST_WITH_COMPLETION
+
+VOID
+FilterForwardRequestWithCompletionRoutine(
+ IN WDFREQUEST Request,
+ IN WDFIOTARGET Target
+ )
+/*++
+Routine Description:
+
+ This routine forwards the request to a lower driver with
+ a completion so that when the request is completed by the
+ lower driver, it can regain control of the request and look
+ at the result.
+
+--*/
+{
+ BOOLEAN ret;
+ NTSTATUS status;
+
+ //
+ // The following funciton essentially copies the content of
+ // current stack location of the underlying IRP to the next one.
+ //
+ WdfRequestFormatRequestUsingCurrentType(Request);
+
+ WdfRequestSetCompletionRoutine(Request,
+ FilterRequestCompletionRoutine,
+ WDF_NO_CONTEXT);
+
+ ret = WdfRequestSend(Request,
+ Target,
+ WDF_NO_SEND_OPTIONS);
+
+ if (ret == FALSE) {
+ status = WdfRequestGetStatus (Request);
+ KdPrint( ("WdfRequestSend failed: 0x%x\n", status));
+ WdfRequestComplete(Request, status);
+ }
+
+ return;
+}
+
+VOID
+FilterRequestCompletionRoutine(
+ IN WDFREQUEST Request,
+ IN WDFIOTARGET Target,
+ PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
+ IN WDFCONTEXT Context
+ )
+/*++
+
+Routine Description:
+
+ Completion Routine
+
+Arguments:
+
+ Target - Target handle
+ Request - Request handle
+ Params - request completion params
+ Context - Driver supplied context
+
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Target);
+ UNREFERENCED_PARAMETER(Context);
+
+ WdfRequestComplete(Request, CompletionParams->IoStatus.Status);
+
+ return;
+}
+
+#endif //FORWARD_REQUEST_WITH_COMPLETION
+
+
+
+
diff --git a/general/toaster/umdf2/filter/generic/filter.h b/general/toaster/umdf2/filter/generic/filter.h
new file mode 100644
index 00000000..e9042c29
--- /dev/null
+++ b/general/toaster/umdf2/filter/generic/filter.h
@@ -0,0 +1,85 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ filter.h
+
+Abstract:
+
+ Contains structure definitions and function prototypes for a generic filter driver.
+
+Environment:
+
+ User mode
+
+--*/
+
+#include <windows.h>
+#include <winioctl.h>
+#pragma warning( disable: 4201 ) // nonstandard extension used : nameless struct/union
+#include <ntstatus.h>
+#include <devpropdef.h>
+#include <wudfwdm.h>
+#include <wdf.h>
+
+#if !defined(_FILTER_H_)
+#define _FILTER_H_
+
+
+#define DRIVERNAME "Generic.sys: "
+
+//
+// Change the following define to 1 if you want to forward
+// the request with a completion routine.
+//
+#define FORWARD_REQUEST_WITH_COMPLETION 0
+
+
+typedef struct _FILTER_EXTENSION
+{
+ WDFDEVICE WdfDevice;
+ // More context data here
+
+}FILTER_EXTENSION, *PFILTER_EXTENSION;
+
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FILTER_EXTENSION,
+ FilterGetData)
+
+DRIVER_INITIALIZE DriverEntry;
+EVT_WDF_DRIVER_DEVICE_ADD FilterEvtDeviceAdd;
+EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL FilterEvtIoDeviceControl;
+
+VOID
+FilterForwardRequest(
+ IN WDFREQUEST Request,
+ IN WDFIOTARGET Target
+ );
+
+#if FORWARD_REQUEST_WITH_COMPLETION
+
+VOID
+FilterForwardRequestWithCompletionRoutine(
+ IN WDFREQUEST Request,
+ IN WDFIOTARGET Target
+ );
+
+VOID
+FilterRequestCompletionRoutine(
+ IN WDFREQUEST Request,
+ IN WDFIOTARGET Target,
+ PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
+ IN WDFCONTEXT Context
+ );
+
+#endif //FORWARD_REQUEST_WITH_COMPLETION
+
+#endif
+
diff --git a/general/toaster/umdf2/filter/generic/filter.rc b/general/toaster/umdf2/filter/generic/filter.rc
new file mode 100644
index 00000000..0c108f44
--- /dev/null
+++ b/general/toaster/umdf2/filter/generic/filter.rc
@@ -0,0 +1,12 @@
+#include <windows.h>
+#include <filter.h>
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DLL
+#define VER_FILESUBTYPE VFT_UNKNOWN
+#define VER_FILEDESCRIPTION_STR "UMDF 2.0 Filter Driver for the Toaster Stack"
+#define VER_INTERNALNAME_STR DRIVERNAME
+#define VER_ORIGINALFILENAME_STR DRIVERNAME
+
+#include "common.ver"
+
diff --git a/general/toaster/umdf2/filter/generic/filterum.inx b/general/toaster/umdf2/filter/generic/filterum.inx
new file mode 100644
index 00000000..3e7013ae
--- /dev/null
+++ b/general/toaster/umdf2/filter/generic/filterum.inx
@@ -0,0 +1,98 @@
+;/*++
+;
+;Copyright (c) Microsoft Corporation. All rights reserved.
+;
+;Module Name:
+;
+; filterum.INF
+;
+;--*/
+
+[Version]
+Signature="$WINDOWS NT$"
+Class=TOASTER
+ClassGuid={B85B7C50-6A01-11d2-B841-00C04FAD5171}
+Provider=%MSFT%
+DriverVer=06/16/1999,5.00.2064
+CatalogFile=wudf.cat
+
+[DestinationDirs]
+DefaultDestDir = 12
+
+; ================= Class section =====================
+
+[ClassInstall32]
+Addreg=ToasterClassReg
+
+[ToasterClassReg]
+HKR,,,0,%ClassName%
+HKR,,Icon,,100
+HKR,,DeviceCharacteristics,0x10001,0x100 ;Use same security checks on relative opens
+HKR,,Security,,"D:P(A;;GA;;;SY)(A;;GA;;;BA)" ;Allow generic all access to system and built-in Admin.
+ ;This one overrides the security set by the driver
+
+;*****************************************
+; Toaster Device Install Section
+;*****************************************
+
+[Manufacturer]
+%StdMfg%=Standard,NT$ARCH$
+
+
+; For XP and later
+[Standard.NT$ARCH$]
+%WdfSimpleDevice.DeviceDesc%=Toaster_Device, root\toaster
+
+[Toaster_Device.NT]
+CopyFiles=UMDriverCopy
+
+; ---------------- file copy
+[UMDriverCopy]
+wdfsimpleum.dll,,,0x00004000 ; COPYFLG_IN_USE_RENAME
+filterum.dll,,,0x00004000 ; COPYFLG_IN_USE_RENAME
+
+[DestinationDirs]
+UMDriverCopy=12,UMDF ; copy to drivers/umdf
+
+[SourceDisksNames]
+1 = %DiskId1%,,,""
+
+[SourceDisksFiles]
+wdfsimpleum.dll = 1,,
+filterum.dll = 1,,
+
+;-------------- Service installation
+
+[Toaster_Device.NT.Services]
+AddService=WUDFRd,0x000001fa,WUDFRD_ServiceInstall
+
+[WUDFRD_ServiceInstall]
+DisplayName = %WudfRdDisplayName%
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %12%\WUDFRd.sys
+
+;-------------- WDF specific section -------------
+[Toaster_Device.NT.Wdf]
+UmdfService=wdfsimpleum, wdfsimple_Install
+UmdfService=filterum, filter_Install
+UmdfServiceOrder=wdfsimpleum, filterum
+
+[wdfsimple_Install]
+UmdfLibraryVersion=$UMDFVERSION$
+ServiceBinary=%12%\UMDF\wdfsimpleum.dll
+
+[filter_Install]
+UmdfLibraryVersion=$UMDFVERSION$
+ServiceBinary=%12%\UMDF\filterum.dll
+
+[Strings]
+SPSVCINST_ASSOCSERVICE= 0x00000002
+MSFT = "Microsoft"
+StdMfg = "(Standard system devices)"
+DiskId1 = "WDF Sample Toaster Installation Disk #1"
+WdfSimpleDevice.DeviceDesc = "Sample WDF Toaster Service + Filter"
+ClassName = "Toaster"
+WudfRdDisplayName="Windows Driver Foundation - User-mode Driver Framework Reflector"
+
diff --git a/general/toaster/umdf2/filter/generic/filterum.vcxproj b/general/toaster/umdf2/filter/generic/filterum.vcxproj
new file mode 100644
index 00000000..d1f340e4
--- /dev/null
+++ b/general/toaster/umdf2/filter/generic/filterum.vcxproj
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{A60F76D2-C512-4DA6-8C80-263F1B506267}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ <SupportsPackaging>false</SupportsPackaging>
+ <RequiresPackageProject>true</RequiresPackageProject>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{0B7A9ABA-5822-49BC-84D3-571A2C7F009A}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems">
+ <Inf Include=".\filterum.inx">
+ <Architecture>$(InfArch)</Architecture>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <CopyOutput>.\$(IntDir)\filterum.inf</CopyOutput>
+ </Inf>
+ </ItemGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>filterum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>filterum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>filterum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>filterum</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <TreatWarningAsError>true</TreatWarningAsError>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="filter.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/filter/generic/filterum.vcxproj.Filters b/general/toaster/umdf2/filter/generic/filterum.vcxproj.Filters
new file mode 100644
index 00000000..e36af926
--- /dev/null
+++ b/general/toaster/umdf2/filter/generic/filterum.vcxproj.Filters
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{DD0D84E8-FA6D-4F21-A94F-490114347147}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{D308818F-2345-4AAC-AE3A-51BD7F250DE2}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{79C52444-6CA6-4417-BC6A-85DD2B63D65C}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{D5C7C2FC-CFB2-4B65-879D-EE3C6847D48D}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include=".\Debug\\filterum.inf">
+ <Filter>Driver Files</Filter>
+ </FilesToPackage>
+ <Inf Include=".\filterum.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="filter.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/func/featured/power.c b/general/toaster/umdf2/func/featured/power.c
new file mode 100644
index 00000000..60b5df78
--- /dev/null
+++ b/general/toaster/umdf2/func/featured/power.c
@@ -0,0 +1,385 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ Power.C
+
+Abstract:
+
+ Implements callbacks to manager power transition, wait-wake and selective
+ suspend.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "toaster.h"
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE, ToasterEvtDeviceD0Exit)
+#pragma alloc_text(PAGE, ToasterEvtDeviceArmWakeFromS0)
+#pragma alloc_text(PAGE, ToasterEvtDeviceArmWakeFromSx)
+#pragma alloc_text(PAGE, ToasterEvtDeviceWakeFromS0Triggered)
+#pragma alloc_text(PAGE, DbgDevicePowerString)
+#endif // ALLOC_PRAGMA
+
+
+NTSTATUS
+ToasterEvtDeviceD0Entry(
+ IN WDFDEVICE Device,
+ IN WDF_POWER_DEVICE_STATE RecentPowerState
+ )
+/*++
+Routine Description:
+
+ EvtDeviceD0Entry event is called to program the device to goto
+ D0, which is the working state. The framework calls the driver's
+ EvtDeviceD0Entry callback when the Power manager sends an
+ IRP_MN_SET_POWER-DevicePower request to the driver stack. The Power manager
+ sends this request when the power policy manager of this device stack
+ (probaby the FDO) requests a change in D-state by calling PoRequestPowerIrp.
+
+ This function is not marked pageable because this function is in the
+ device power up path. When a function is marked pagable and the code
+ section is paged out, it will generate a page fault which could impact
+ the fast resume behavior because the client driver will have to wait
+ until the system drivers can service this page fault.
+
+Arguments:
+
+ Device - handle to a framework device object.
+
+ RecentPowerState - WDF_POWER_DEVICE_STATE-typed enumerator that identifies the
+ device power state that the device was in before this transition
+ to D0.
+
+Return Value:
+
+ NTSTATUS - A failure here will indicate a fatal error in the driver.
+ The Framework will attempt to tear down the stack.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(RecentPowerState);
+
+ KdPrint(("ToasterEvtDeviceD0Entry - coming from %s\n",
+ DbgDevicePowerString(RecentPowerState)));
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+ToasterEvtDeviceD0Exit(
+ IN WDFDEVICE Device,
+ IN WDF_POWER_DEVICE_STATE PowerState
+ )
+/*++
+Routine Description:
+
+ EvtDeviceD0Entry event is called to program the device to goto
+ D1, D2 or D3, which are the low-power states. The framework calls the
+ driver's EvtDeviceD0Exit callback when the Power manager sends an
+ IRP_MN_SET_POWER-DevicePower request to the driver stack. The Power manager
+ sends this request when the power policy manager of this device stack
+ (probaby the FDO) requests a change in D-state by calling PoRequestPowerIrp.
+
+Arguments:
+
+ Device - handle to a framework device object.
+
+ DeviceState - WDF_POWER_DEVICE_STATE-typed enumerator that identifies the
+ device power state that the power policy owner (probably the
+ FDO) has decided is appropriate.
+
+Return Value:
+
+ NTSTATUS - A failure here will indicate a fatal error in the driver.
+ The Framework will attempt to tear down the stack.
+--*/
+{
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(PowerState);
+
+ PAGED_CODE();
+
+ KdPrint(("ToasterEvtDeviceD0Exit %s\n",
+ DbgDevicePowerString(PowerState)));
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+ToasterEvtDeviceArmWakeFromS0(
+ IN WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceArmWakeFromS0 is called when the Framework arms the device for
+ wake from S0. If there is any device-specific initialization
+ that needs to be done to arm internal wake signals, or to route internal
+ interrupt signals to the wake logic, it should be done here. The device
+ will be moved out of the D0 state soon after this callback is invoked.
+
+ This function is pageable and it will run at PASSIVE_LEVEL.
+
+Arguments:
+
+ Device - Handle to a Framework device object.
+
+Return Value:
+
+ NTSTATUS - Failure will result in the device remaining in the D0 state.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Device);
+
+ PAGED_CODE();
+
+ KdPrint(( "--> ToasterEvtDeviceArmWakeFromS0\n"));
+
+ KdPrint(( "<-- ToasterEvtDeviceArmWakeFromS0\n"));
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+ToasterEvtDeviceArmWakeFromSx(
+ IN WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceArmWakeFromSx is called when the Framework arms the device for
+ wake from Sx. If there is any device-specific initialization
+ that needs to be done to arm internal wake signals, or to route internal
+ interrupt signals to the wake logic, it should be done here. The device
+ will be moved out of the D0 state soon after this callback is invoked.
+
+ This function is pageable and it will run at PASSIVE_LEVEL.
+
+Arguments:
+
+ Device - Handle to a Framework device object.
+
+Return Value:
+
+ NTSTATUS - Failure will result in the device remaining in the D0 state.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Device);
+
+ PAGED_CODE();
+
+ KdPrint(( "--> ToasterEvtDeviceArmWakeFromSx\n"));
+
+ KdPrint(( "<-- ToasterEvtDeviceArmWakeFromSx\n"));
+
+ return STATUS_SUCCESS;
+}
+
+VOID
+ToasterEvtDeviceDisarmWakeFromS0(
+ IN WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceDisarmWakeFromS0 reverses anything done in EvtDeviceArmWakeFromS0.
+
+ This function is not marked pageable because this function is in the
+ device power up path. When a function is marked pagable and the code
+ section is paged out, it will generate a page fault which could impact
+ the fast resume behavior because the client driver will have to wait
+ until the system drivers can service this page fault.
+
+Arguments:
+
+ Device - Handle to a Framework device object.
+
+Return Value:
+
+ VOID.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Device);
+
+ KdPrint(( "--> ToasterEvtDeviceDisarmWakeFromS0\n"));
+
+ KdPrint(( "<-- ToasterEvtDeviceDisarmWakeFromS0\n"));
+
+ return ;
+}
+
+VOID
+ToasterEvtDeviceDisarmWakeFromSx(
+ IN WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceDisarmWakeFromSx reverses anything done in EvtDeviceArmWakeFromSx.
+
+ This function will run at PASSIVE_LEVEL.
+
+ This function is not marked pageable because this function is in the
+ device power up path. When a function is marked pagable and the code
+ section is paged out, it will generate a page fault which could impact
+ the fast resume behavior because the client driver will have to wait
+ until the system drivers can service this page fault.
+
+Arguments:
+
+ Device - Handle to a Framework device object.
+
+Return Value:
+
+ VOID.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Device);
+
+ KdPrint(( "--> ToasterEvtDeviceDisarmWakeFromSx\n"));
+
+ KdPrint(( "<-- ToasterEvtDeviceDisarmWakeFromSx\n"));
+
+ return ;
+}
+
+VOID
+ToasterEvtDeviceWakeFromS0Triggered(
+ IN WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceWakeFromS0Triggered will be called whenever the device triggers its
+ wake signal after being armed for wake.
+
+ This function is pageable and runs at PASSIVE_LEVEL.
+
+Arguments:
+
+ Device - Handle to a Framework device object.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Device);
+
+ PAGED_CODE();
+
+ KdPrint(( "--> ToasterEvtDeviceWakeFromS0Triggered\n"));
+
+
+ KdPrint(( "<-- ToasterEvtDeviceWakeFromS0Triggered\n"));
+
+}
+
+VOID
+ToasterEvtDeviceWakeFromSxTriggered(
+ IN WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceWakeFromSxTriggered will be called whenever the device triggers its
+ wake signal after being armed for wake.
+
+ This function runs at PASSIVE_LEVEL.
+
+ This function is not marked pageable because this function is in the
+ device power up path. When a function is marked pagable and the code
+ section is paged out, it will generate a page fault which could impact
+ the fast resume behavior because the client driver will have to wait
+ until the system drivers can service this page fault.
+
+Arguments:
+
+ Device - Handle to a Framework device object.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Device);
+
+ KdPrint(( "--> ToasterEvtDeviceWakeFromSxTriggered\n"));
+
+ KdPrint(( "<-- ToasterEvtDeviceWakeFromSxTriggered\n"));
+
+}
+
+PCHAR
+DbgDevicePowerString(
+ IN WDF_POWER_DEVICE_STATE Type
+ )
+/*++
+
+New Routine Description:
+ DbgDevicePowerString converts the device power state code of a power IRP to a
+ text string that is helpful when tracing the execution of power IRPs.
+
+Parameters Description:
+ Type
+ Type specifies the device power state code of a power IRP.
+
+Return Value Description:
+ DbgDevicePowerString returns a pointer to a string that represents the
+ text description of the incoming device power state code.
+
+--*/
+{
+ PAGED_CODE();
+
+ switch (Type)
+ {
+ case WdfPowerDeviceInvalid:
+ return "WdfPowerDeviceInvalid";
+ case WdfPowerDeviceD0:
+ return "WdfPowerDeviceD0";
+ case WdfPowerDeviceD1:
+ return "WdfPowerDeviceD1";
+ case WdfPowerDeviceD2:
+ return "WdfPowerDeviceD2";
+ case WdfPowerDeviceD3:
+ return "WdfPowerDeviceD3";
+ case WdfPowerDeviceD3Final:
+ return "WdfPowerDeviceD3Final";
+ case WdfPowerDevicePrepareForHibernation:
+ return "WdfPowerDevicePrepareForHibernation";
+ case WdfPowerDeviceMaximum:
+ return "WdfPowerDeviceMaximum";
+ default:
+ return "UnKnown Device Power State";
+ }
+}
+
+
+
+
diff --git a/general/toaster/umdf2/func/featured/toaster.c b/general/toaster/umdf2/func/featured/toaster.c
new file mode 100644
index 00000000..c25eebd4
--- /dev/null
+++ b/general/toaster/umdf2/func/featured/toaster.c
@@ -0,0 +1,862 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ Toaster.c
+
+Abstract:
+
+ This is a featured version of the toaster function driver. This version
+ shows how to register for PNP and Power events, handle create & close
+ file requests.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "toaster.h"
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text (INIT, DriverEntry)
+#pragma alloc_text (PAGE, ToasterEvtDeviceAdd)
+#pragma alloc_text (PAGE, ToasterEvtDeviceFileCreate)
+#pragma alloc_text (PAGE, ToasterEvtFileClose)
+#pragma alloc_text (PAGE, ToasterEvtDevicePrepareHardware)
+#pragma alloc_text (PAGE, ToasterEvtDeviceReleaseHardware)
+#pragma alloc_text (PAGE, ToasterEvtDeviceContextCleanup)
+#pragma alloc_text (PAGE, ToasterEvtIoDeviceControl)
+#pragma alloc_text (PAGE, ToasterEvtIoRead)
+#pragma alloc_text (PAGE, ToasterEvtIoWrite)
+#endif
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+ DriverEntry initializes the driver and is the first routine called by the
+ system after the driver is loaded. DriverEntry specifies the other entry
+ points in the function driver, such as ToasterAddDevice and ToasterUnload.
+
+Parameters Description:
+
+ DriverObject - represents the instance of the function driver that is loaded
+ into memory. DriverEntry must initialize members of DriverObject before it
+ returns to the caller. DriverObject is allocated by the system before the
+ driver is loaded, and it is released by the system after the system unloads
+ the function driver from memory.
+
+ RegistryPath - represents the driver specific path in the Registry.
+ The function driver can use the path to store driver related data between
+ reboots. The path does not store hardware instance specific data.
+
+Return Value:
+
+ STATUS_SUCCESS if successful,
+ STATUS_UNSUCCESSFUL otherwise.
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ WDF_DRIVER_CONFIG config;
+
+ KdPrint(("WDF Toaster Function Driver Sample - Featured version\n"));
+
+ //
+ // Initiialize driver config to control the attributes that
+ // are global to the driver. Note that framework by default
+ // provides a driver unload routine. If you create any resources
+ // in the DriverEntry and want to be cleaned in driver unload,
+ // you can override that by manually setting the EvtDriverUnload in the
+ // config structure. In general xxx_CONFIG_INIT macros are provided to
+ // initialize most commonly used members.
+ //
+
+ WDF_DRIVER_CONFIG_INIT(
+ &config,
+ ToasterEvtDeviceAdd
+ );
+
+ //
+ // Create a framework driver object to represent our driver.
+ //
+ status = WdfDriverCreate(
+ DriverObject,
+ RegistryPath,
+ WDF_NO_OBJECT_ATTRIBUTES, // Driver Attributes
+ &config, // Driver Config Info
+ WDF_NO_HANDLE
+ );
+
+ if (!NT_SUCCESS(status)) {
+ KdPrint( ("WdfDriverCreate failed with status 0x%x\n", status));
+ }
+
+ return status;
+}
+
+
+NTSTATUS
+ToasterEvtDeviceAdd(
+ IN WDFDRIVER Driver,
+ IN PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+Routine Description:
+
+ ToasterEvtDeviceAdd is called by the framework in response to AddDevice
+ call from the PnP manager. We create and initialize a device object to
+ represent a new instance of toaster device.
+
+Arguments:
+
+ Driver - Handle to a framework driver object created in DriverEntry
+
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
+ WDF_OBJECT_ATTRIBUTES fdoAttributes;
+ WDFDEVICE device;
+ WDF_FILEOBJECT_CONFIG fileConfig;
+ WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS idleSettings;
+ WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS wakeSettings;
+ WDF_POWER_POLICY_EVENT_CALLBACKS powerPolicyCallbacks;
+ WDF_IO_QUEUE_CONFIG queueConfig;
+ //PFDO_DATA fdoData;
+ WDFQUEUE queue;
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ PAGED_CODE();
+
+ KdPrint(("ToasterEvtDeviceAdd called\n"));
+
+ //
+ // Initialize the pnpPowerCallbacks structure. Callback events for PNP
+ // and Power are specified here. If you don't supply any callbacks,
+ // the Framework will take appropriate default actions based on whether
+ // DeviceInit is initialized to be an FDO, a PDO or a filter device
+ // object.
+ //
+
+ WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
+
+ //
+ // Register PNP callbacks.
+ //
+ pnpPowerCallbacks.EvtDevicePrepareHardware = ToasterEvtDevicePrepareHardware;
+ pnpPowerCallbacks.EvtDeviceReleaseHardware = ToasterEvtDeviceReleaseHardware;
+ pnpPowerCallbacks.EvtDeviceSelfManagedIoInit = ToasterEvtDeviceSelfManagedIoInit;
+
+ //
+ // Register Power callbacks.
+ //
+ pnpPowerCallbacks.EvtDeviceD0Entry = ToasterEvtDeviceD0Entry;
+ pnpPowerCallbacks.EvtDeviceD0Exit = ToasterEvtDeviceD0Exit;
+
+
+ WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
+
+ //
+ // Register power policy event callbacks so that we would know when to
+ // arm/disarm the hardware to handle wait-wake and when the wake event
+ // is triggered by the hardware.
+ //
+ WDF_POWER_POLICY_EVENT_CALLBACKS_INIT(&powerPolicyCallbacks);
+
+ //
+ // This group of three callbacks allows this sample driver to manage
+ // arming the device for wake from the S0 or Sx state. We don't really
+ // differentiate between S0 and Sx state..
+ //
+ powerPolicyCallbacks.EvtDeviceArmWakeFromS0 = ToasterEvtDeviceArmWakeFromS0;
+ powerPolicyCallbacks.EvtDeviceDisarmWakeFromS0 = ToasterEvtDeviceDisarmWakeFromS0;
+ powerPolicyCallbacks.EvtDeviceWakeFromS0Triggered = ToasterEvtDeviceWakeFromS0Triggered;
+ powerPolicyCallbacks.EvtDeviceArmWakeFromSx = ToasterEvtDeviceArmWakeFromSx;
+ powerPolicyCallbacks.EvtDeviceDisarmWakeFromSx = ToasterEvtDeviceDisarmWakeFromSx;
+ powerPolicyCallbacks.EvtDeviceWakeFromSxTriggered = ToasterEvtDeviceWakeFromSxTriggered;
+
+ //
+ // Register the power policy callbacks.
+ //
+ WdfDeviceInitSetPowerPolicyEventCallbacks(DeviceInit, &powerPolicyCallbacks);
+
+ //
+ // Initialize WDF_FILEOBJECT_CONFIG_INIT struct to tell the
+ // framework whether you are interested in handling Create, Close and
+ // Cleanup requests that gets genereate when an application or another
+ // kernel component opens an handle to the device. If you don't register,
+ // the framework default behaviour would be complete these requests
+ // with STATUS_SUCCESS. A driver might be interested in registering these
+ // events if it wants to do security validation and also wants to maintain
+ // per handle (fileobject) context.
+ //
+
+ WDF_FILEOBJECT_CONFIG_INIT(
+ &fileConfig,
+ ToasterEvtDeviceFileCreate,
+ ToasterEvtFileClose,
+ WDF_NO_EVENT_CALLBACK // not interested in Cleanup
+ );
+
+ WdfDeviceInitSetFileObjectConfig(DeviceInit,
+ &fileConfig,
+ WDF_NO_OBJECT_ATTRIBUTES);
+
+ //
+ // Now specify the size of device extension where we track per device
+ // context. Along with setting the context type as shown below, you should also
+ // specify the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME in header to specify the
+ // accessor function name.
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, FDO_DATA);
+
+ //
+ // Set a context cleanup routine to cleanup any resources that are not
+ // parent to this device. This cleanup will be called in the context of
+ // pnp remove-device when the framework deletes the device object.
+ //
+ fdoAttributes.EvtCleanupCallback = ToasterEvtDeviceContextCleanup;
+
+ //
+ // DeviceInit is completely initialized. So call the framework to create the
+ // device and attach it to the lower stack.
+ //
+ status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &device);
+ if (!NT_SUCCESS(status)) {
+ KdPrint( ("WdfDeviceCreate failed with Status code 0x%x\n", status));
+ return status;
+ }
+
+ //
+ // Get the device context by using accessor function specified in
+ // the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro for FDO_DATA.
+ //
+ //fdoData = ToasterFdoGetData(device);
+
+ //
+ // Tell the Framework that this device will need an interface so that
+ // application can find our device and talk to it.
+ //
+ status = WdfDeviceCreateDeviceInterface(
+ device,
+ (LPGUID) &GUID_DEVINTERFACE_TOASTER,
+ NULL
+ );
+
+ if (!NT_SUCCESS (status)) {
+ KdPrint( ("WdfDeviceCreateDeviceInterface failed 0x%x\n", status));
+ return status;
+ }
+
+ //
+ // Register I/O callbacks to tell the framework that you are interested
+ // in handling IRP_MJ_READ, IRP_MJ_WRITE, and IRP_MJ_DEVICE_CONTROL requests.
+ // In case a specific handler is not specified for one of these,
+ // the request will be dispatched to the EvtIoDefault handler, if any.
+ // If there is no EvtIoDefault handler, the request will be failed with
+ // STATUS_INVALID_DEVICE_REQUEST.
+ // WdfIoQueueDispatchParallel means that we are capable of handling
+ // all the I/O request simultaneously and we are responsible for protecting
+ // data that could be accessed by these callbacks simultaneously.
+ // A default queue gets all the requests that are not
+ // configure-fowarded using WdfDeviceConfigureRequestDispatching.
+ //
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig,
+ WdfIoQueueDispatchParallel); // EvtIoCancel
+
+ queueConfig.EvtIoRead = ToasterEvtIoRead;
+ queueConfig.EvtIoWrite = ToasterEvtIoWrite;
+ queueConfig.EvtIoDeviceControl = ToasterEvtIoDeviceControl;
+
+ //
+ // By default, Static Driver Verifier (SDV) displays a warning if it
+ // doesn't find the EvtIoStop callback on a power-managed queue.
+ // The 'assume' below causes SDV to suppress this warning. If the driver
+ // has not explicitly set PowerManaged to WdfFalse, the framework creates
+ // power-managed queues when the device is not a filter driver. Normally
+ // the EvtIoStop is required for power-managed queues, but for this driver
+ // it is not needed b/c the driver doesn't hold on to the requests or
+ // forward them to other drivers. This driver completes the requests
+ // directly in the queue's handlers. If the EvtIoStop callback is not
+ // implemented, the framework waits for all driver-owned requests to be
+ // done before moving in the Dx/sleep states or before removing the
+ // device, which is the correct behavior for this type of driver.
+ // If the requests were taking an indeterminate amount of time to complete,
+ // or if the driver forwarded the requests to a lower driver/another stack,
+ // the queue should have an EvtIoStop/EvtIoResume.
+ //
+ __analysis_assume(queueConfig.EvtIoStop != 0);
+ status = WdfIoQueueCreate(device,
+ &queueConfig,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &queue
+ );
+ __analysis_assume(queueConfig.EvtIoStop == 0);
+
+ if (!NT_SUCCESS (status)) {
+
+ KdPrint( ("WdfIoQueueCreate failed 0x%x\n", status));
+ return status;
+ }
+
+ //
+ // Set the idle power policy to put the device to Dx if the device is not used
+ // for the specified IdleTimeout time. Since this is a virtual device we
+ // tell the framework that we cannot wake ourself if we sleep in S0. Only
+ // way the device can be brought to D0 is if the device recieves an I/O from
+ // the system.
+ //
+ WDF_DEVICE_POWER_POLICY_IDLE_SETTINGS_INIT(&idleSettings, IdleCannotWakeFromS0);
+ idleSettings.IdleTimeout = 60000; // 60 secs idle timeout
+ status = WdfDeviceAssignS0IdleSettings(device, &idleSettings);
+ if (!NT_SUCCESS(status)) {
+ KdPrint( ("WdfDeviceAssignS0IdleSettings failed 0x%x\n", status));
+ return status;
+ }
+
+ //
+ // Set the wait-wake policy.
+ //
+
+ WDF_DEVICE_POWER_POLICY_WAKE_SETTINGS_INIT(&wakeSettings);
+ status = WdfDeviceAssignSxWakeSettings(device, &wakeSettings);
+ if (!NT_SUCCESS(status)) {
+ //
+ // We are probably enumerated on a bus that doesn't support Sx-wake.
+ // Let us not fail the device add just because we aren't able to support
+ // wait-wake. I will let the user of this sample decide how important it's
+ // to support wait-wake for their hardware and return appropriate status.
+ //
+ KdPrint( ("WdfDeviceAssignSxWakeSettings failed 0x%x\n", status));
+ status = STATUS_SUCCESS;
+ }
+
+ return status;
+}
+
+NTSTATUS
+ToasterEvtDevicePrepareHardware(
+ WDFDEVICE Device,
+ WDFCMRESLIST ResourcesRaw,
+ WDFCMRESLIST ResourcesTranslated
+ )
+/*++
+
+Routine Description:
+
+ EvtDevicePrepareHardware event callback performs operations that are
+ necessary to make the driver's device operational. The framework calls the
+ driver's EvtDevicePrepareHardware callback when the PnP manager sends an
+ IRP_MN_START_DEVICE request to the driver stack.
+
+ Specifically, most drivers will use this callback to map resources. USB
+ drivers may use it to get device descriptors, config descriptors and to
+ select configs.
+
+ Some drivers may choose to download firmware to a device in this callback,
+ but that is usually only a good choice if the device firmware won't be
+ destroyed by a D0 to D3 transition. If firmware will be gone after D3,
+ then firmware downloads should be done in EvtDeviceD0Entry, not here.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+ ResourcesRaw - Handle to a collection of framework resource objects.
+ This collection identifies the raw (bus-relative) hardware
+ resources that have been assigned to the device.
+
+ ResourcesTranslated - Handle to a collection of framework resource objects.
+ This collection identifies the translated (system-physical)
+ hardware resources that have been assigned to the device.
+ The resources appear from the CPU's point of view.
+ Use this list of resources to map I/O space and
+ device-accessible memory into virtual address space
+
+Return Value:
+
+ WDF status code
+
+--*/
+{
+ //PFDO_DATA fdoData;
+ NTSTATUS status = STATUS_SUCCESS;
+ ULONG i;
+ PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
+
+ //fdoData = ToasterFdoGetData(Device);
+
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(ResourcesRaw);
+
+ KdPrint(("ToasterEvtDevicePrepareHardware called\n"));
+
+ PAGED_CODE();
+ //
+ // Get the number item that are currently in Resources collection and
+ // iterate thru as many times to get more information about the each items
+ //
+ for (i=0; i < WdfCmResourceListGetCount(ResourcesTranslated); i++) {
+
+ descriptor = WdfCmResourceListGetDescriptor(ResourcesTranslated, i);
+
+ switch(descriptor->Type) {
+
+ case CmResourceTypePort:
+
+ KdPrint(("I/O Port: (%x) Length: (%d)\n",
+ descriptor->u.Port.Start.LowPart,
+ descriptor->u.Port.Length));
+ break;
+
+ case CmResourceTypeMemory:
+
+ KdPrint(("Memory: (%x) Length: (%d)\n",
+ descriptor->u.Memory.Start.LowPart,
+ descriptor->u.Memory.Length));
+ break;
+ case CmResourceTypeInterrupt:
+
+ KdPrint(("Interrupt level: 0x%0x, Vector: 0x%0x, Affinity: 0x%0Ix\n",
+ descriptor->u.Interrupt.Level,
+ descriptor->u.Interrupt.Vector,
+ descriptor->u.Interrupt.Affinity));
+ break;
+
+ default:
+ break;
+ }
+
+ }
+
+ return status;
+
+}
+
+NTSTATUS
+ToasterEvtDeviceReleaseHardware(
+ IN WDFDEVICE Device,
+ IN WDFCMRESLIST ResourcesTranslated
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceReleaseHardware is called by the framework whenever the PnP manager
+ is revoking ownership of our resources. This may be in response to either
+ IRP_MN_STOP_DEVICE or IRP_MN_REMOVE_DEVICE. The callback is made before
+ passing down the IRP to the lower driver.
+
+ In this callback, do anything necessary to free those resources.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+ ResourcesTranslated - Handle to a collection of framework resource objects.
+ This collection identifies the translated (system-physical)
+ hardware resources that have been assigned to the device.
+ The resources appear from the CPU's point of view.
+ Use this list of resources to map I/O space and
+ device-accessible memory into virtual address space
+
+Return Value:
+
+ NTSTATUS - Failures will be logged, but not acted on.
+
+--*/
+{
+ //PFDO_DATA fdoData;
+
+ UNREFERENCED_PARAMETER(Device);
+ UNREFERENCED_PARAMETER(ResourcesTranslated);
+
+ KdPrint(("ToasterEvtDeviceReleaseHardware called\n"));
+
+ PAGED_CODE();
+
+ //fdoData = ToasterFdoGetData(Device);
+ //
+ // Unmap any I/O ports, registers that you mapped in PrepareHardware.
+ // Disconnecting from the interrupt will be done automatically by the framework.
+ //
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+ToasterEvtDeviceSelfManagedIoInit(
+ IN WDFDEVICE Device
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceSelfManagedIoInit is called it once for each device,
+ after the framework has called the driver's EvtDeviceD0Entry
+ callback function for the first time. The framework does not
+ call the EvtDeviceSelfManagedIoInit callback function again for
+ that device, unless the device is removed and reconnected, or
+ the drivers are reloaded.
+
+ The EvtDeviceSelfManagedIoInit callback function must initialize
+ the self-managed I/O operations that the driver will handle
+ for the device.
+
+ This function is not marked pageable because this function is in the
+ device power up path. When a function is marked pagable and the code
+ section is paged out, it will generate a page fault which could impact
+ the fast resume behavior because the client driver will have to wait
+ until the system drivers can service this page fault.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+Return Value:
+
+ NTSTATUS - Failures will result in the device stack being torn down.
+
+--*/
+{
+ UNREFERENCED_PARAMETER(Device);
+
+ KdPrint(("ToasterEvtDeviceSelfManagedIoInit called\n"));
+
+ return STATUS_SUCCESS;
+}
+
+
+VOID
+ToasterEvtDeviceContextCleanup(
+ IN WDFOBJECT Device
+ )
+/*++
+
+Routine Description:
+
+ EvtDeviceContextCleanup event callback must perform any operations that are
+ necessary before the specified device is removed. The framework calls
+ the driver's EvtDeviceContextCleanup callback when the device is deleted in response
+ to IRP_MN_REMOVE_DEVICE request.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+
+Return Value:
+
+ None
+
+--*/
+{
+ //PFDO_DATA fdoData;
+ UNREFERENCED_PARAMETER(Device);
+ KdPrint( ("ToasterEvtDeviceContextCleanup called\n"));
+
+ PAGED_CODE();
+
+ //fdoData = ToasterFdoGetData((WDFDEVICE)Device);
+
+ return;
+}
+
+VOID
+ToasterEvtDeviceFileCreate (
+ IN WDFDEVICE Device,
+ IN WDFREQUEST Request,
+ IN WDFFILEOBJECT FileObject
+ )
+/*++
+
+Routine Description:
+
+ The framework calls a driver's EvtDeviceFileCreate callback
+ when the framework receives an IRP_MJ_CREATE request.
+ The system sends this request when a user application opens the
+ device to perform an I/O operation, such as reading or writing to a device.
+ This callback is called in the context of the thread
+ that created the IRP_MJ_CREATE request.
+
+Arguments:
+
+ Device - Handle to a framework device object.
+ FileObject - Pointer to fileobject that represents the open handle.
+ CreateParams - Parameters for create
+
+Return Value:
+
+ None
+
+--*/
+{
+ //PFDO_DATA fdoData;
+
+ UNREFERENCED_PARAMETER(FileObject);
+ UNREFERENCED_PARAMETER(Device);
+
+ KdPrint( ("ToasterEvtDeviceFileCreate %p\n", Device));
+
+ PAGED_CODE ();
+
+ //
+ // Get the device context given the device handle.
+ //
+ //fdoData = ToasterFdoGetData(Device);
+
+ WdfRequestComplete(Request, STATUS_SUCCESS);
+
+ return;
+}
+
+
+VOID
+ToasterEvtFileClose (
+ IN WDFFILEOBJECT FileObject
+ )
+
+/*++
+
+Routine Description:
+
+ EvtFileClose is called when all the handles represented by the FileObject
+ is closed and all the references to FileObject is removed. This callback
+ may get called in an arbitrary thread context instead of the thread that
+ called CloseHandle. If you want to delete any per FileObject context that
+ must be done in the context of the user thread that made the Create call,
+ you should do that in the EvtDeviceCleanp callback.
+
+Arguments:
+
+ FileObject - Pointer to fileobject that represents the open handle.
+
+Return Value:
+
+ None
+
+--*/
+{
+ //PFDO_DATA fdoData;
+ UNREFERENCED_PARAMETER(FileObject);
+ PAGED_CODE ();
+
+ //fdoData = ToasterFdoGetData(WdfFileObjectGetDevice(FileObject));
+
+ KdPrint( ("ToasterEvtFileClose\n"));
+
+ return;
+}
+
+
+
+VOID
+ToasterEvtIoRead (
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t Length
+ )
+/*++
+
+Routine Description:
+
+ Performs read to the toaster device. This event is called when the
+ framework receives IRP_MJ_READ requests.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated with the
+ I/O request.
+ Request - Handle to a framework request object.
+
+ Lenght - Length of the data buffer associated with the request.
+ The default property of the queue is to not dispatch
+ zero lenght read & write requests to the driver and
+ complete is with status success. So we will never get
+ a zero length request.
+
+Return Value:
+
+ None
+
+--*/
+{
+ NTSTATUS status;
+ ULONG_PTR bytesCopied =0;
+ WDFMEMORY memory;
+
+ UNREFERENCED_PARAMETER(Length);
+ UNREFERENCED_PARAMETER(Queue);
+
+ PAGED_CODE();
+
+ KdPrint(("ToasterEvtIoRead: Request: 0x%p, Queue: 0x%p\n",
+ Request, Queue));
+
+ //
+ // Get the request memory and perform read operation here
+ //
+ status = WdfRequestRetrieveOutputMemory(Request, &memory);
+ if(NT_SUCCESS(status) ) {
+ //
+ // Copy data into the memory buffer using WdfMemoryCopyFromBuffer
+ //
+ }
+
+ WdfRequestCompleteWithInformation(Request, status, bytesCopied);
+
+}
+
+VOID
+ToasterEvtIoWrite (
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t Length
+ )
+/*++
+
+Routine Description:
+
+ Performs write to the toaster device. This event is called when the
+ framework receives IRP_MJ_WRITE requests.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated with the
+ I/O request.
+ Request - Handle to a framework request object.
+
+ Lenght - Length of the data buffer associated with the request.
+ The default property of the queue is to not dispatch
+ zero lenght read & write requests to the driver and
+ complete is with status success. So we will never get
+ a zero length request.
+
+Return Value:
+
+ None
+
+--*/
+
+{
+ NTSTATUS status;
+ WDFMEMORY memory;
+
+ UNREFERENCED_PARAMETER(Queue);
+
+ KdPrint(("ToasterEvtIoWrite. Request: 0x%p, Queue: 0x%p\n",
+ Request, Queue));
+ PAGED_CODE();
+
+ //
+ // Get the request buffer and perform write operation here
+ //
+ status = WdfRequestRetrieveInputMemory(Request, &memory);
+ if(NT_SUCCESS(status) ) {
+ //
+ // 1) Use WdfMemoryCopyToBuffer to copy data from the request
+ // to driver buffer.
+ // 2) Or get the buffer pointer from the request by calling
+ // WdfRequestRetrieveInputBuffer to transfer data to the hw
+ // 3) Or you can get the buffer pointer from the memory handle
+ // by calling WdfMemoryGetBuffer to transfer data to the hw.
+ //
+ }
+
+ WdfRequestCompleteWithInformation(Request, status, Length);
+
+}
+
+
+VOID
+ToasterEvtIoDeviceControl(
+ IN WDFQUEUE Queue,
+ IN WDFREQUEST Request,
+ IN size_t OutputBufferLength,
+ IN size_t InputBufferLength,
+ IN ULONG IoControlCode
+ )
+/*++
+Routine Description:
+
+ This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
+ requests from the system.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated
+ with the I/O request.
+ Request - Handle to a framework request object.
+
+ OutputBufferLength - length of the request's output buffer,
+ if an output buffer is available.
+ InputBufferLength - length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - the driver-defined or system-defined I/O control code
+ (IOCTL) that is associated with the request.
+
+Return Value:
+
+ None
+
+--*/
+{
+ NTSTATUS status= STATUS_SUCCESS;
+ WDF_DEVICE_STATE deviceState;
+ WDFDEVICE hDevice = WdfIoQueueGetDevice(Queue);
+
+
+ UNREFERENCED_PARAMETER(OutputBufferLength);
+ UNREFERENCED_PARAMETER(InputBufferLength);
+
+ KdPrint(("ToasterEvtIoDeviceControl called\n"));
+
+ PAGED_CODE();
+
+ switch (IoControlCode) {
+
+ case IOCTL_TOASTER_DONT_DISPLAY_IN_UI_DEVICE:
+ //
+ // This is just an example on how to hide your device in the
+ // device manager. Please remove this code when you adapt
+ // this sample for your hardware.
+ //
+ WDF_DEVICE_STATE_INIT(&deviceState);
+ deviceState.DontDisplayInUI = WdfTrue;
+ WdfDeviceSetDeviceState(
+ hDevice,
+ &deviceState
+ );
+ break;
+
+ default:
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ //
+ // Complete the Request.
+ //
+ WdfRequestCompleteWithInformation(Request, status, (ULONG_PTR) 0);
+
+}
+
+
diff --git a/general/toaster/umdf2/func/featured/toaster.rc b/general/toaster/umdf2/func/featured/toaster.rc
new file mode 100644
index 00000000..e9ba2ea8
--- /dev/null
+++ b/general/toaster/umdf2/func/featured/toaster.rc
@@ -0,0 +1,12 @@
+#include <windows.h>
+
+#include <ntverp.h>
+
+#define VER_FILETYPE VFT_DLL
+#define VER_FILESUBTYPE VFT_UNKNOWN
+#define VER_FILEDESCRIPTION_STR "WDF UMDF2 Toaster Device Driver"
+#define VER_INTERNALNAME_STR "wdftoaster.dll"
+#define VER_ORIGINALFILENAME_STR "wdftoaster.dll"
+
+#include "common.ver"
+
diff --git a/general/toaster/umdf2/func/featured/wdffeaturedum.inx b/general/toaster/umdf2/func/featured/wdffeaturedum.inx
new file mode 100644
index 00000000..feae7a33
--- /dev/null
+++ b/general/toaster/umdf2/func/featured/wdffeaturedum.inx
@@ -0,0 +1,98 @@
+;/*++
+;
+;Copyright (c) Microsoft Corporation. All rights reserved.
+;
+;Module Name:
+; wdffeatured.INF
+;
+;Abstract:
+; INF file for installing the UMDF2 Toaster Driver
+;
+;Installation Notes:
+; Using Devcon: Type "devcon install wdffeaturedum.inf root\toaster" to install
+;
+;--*/
+
+[Version]
+Signature="$WINDOWS NT$"
+Class=TOASTER
+ClassGuid={B85B7C50-6A01-11d2-B841-00C04FAD5171}
+Provider=%MSFT%
+DriverVer=03/20/2003,5.00.3788
+CatalogFile=wudf.cat
+
+[DestinationDirs]
+DefaultDestDir = 12
+
+; ================= Class section =====================
+
+[ClassInstall32]
+Addreg=ToasterClassReg
+
+[ToasterClassReg]
+HKR,,,0,%ClassName%
+HKR,,Icon,,100
+HKR,,DeviceCharacteristics,0x10001,0x100 ;Use same security checks on relative opens
+HKR,,Security,,"D:P(A;;GA;;;SY)(A;;GA;;;BA)" ;Allow generic all access to system and built-in Admin.
+ ;This one overrides the security set by the driver
+
+[SourceDisksNames]
+1 = %DiskId1%,,,""
+
+[SourceDisksFiles]
+wdffeaturedum.dll = 1,,
+
+;*****************************************
+; Toaster Install Section
+;*****************************************
+
+[Manufacturer]
+%StdMfg%=Standard,NT$ARCH$
+
+;
+; Hw Id is root\toaster
+;
+[Standard.NT$ARCH$]
+%Toaster.DeviceDesc%=Toaster_Device, root\toaster
+
+;---------------- copy files
+
+[Toaster_Device.NT]
+CopyFiles=UMDriverCopy
+
+[UMDriverCopy]
+wdffeaturedum.dll,,,0x00004000 ; COPYFLG_IN_USE_RENAME
+
+[DestinationDirs]
+UMDriverCopy=12,UMDF ; copy to drivers\umdf
+
+;-------------- Service installation
+[Toaster_Device.NT.Services]
+AddService=WUDFRd,0x000001fa,WUDFRD_ServiceInstall
+
+[WUDFRD_ServiceInstall]
+DisplayName = %WudfRdDisplayName%
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %12%\WUDFRd.sys
+
+;-------------- WDF specific section -------------
+[Toaster_Device.NT.Wdf]
+UmdfService=wdffeaturedum, Toaster_Install
+UmdfServiceOrder=wdffeaturedum
+
+[Toaster_Install]
+UmdfLibraryVersion=$UMDFVERSION$
+ServiceBinary=%12%\UMDF\wdffeaturedum.dll
+
+[Strings]
+SPSVCINST_ASSOCSERVICE= 0x00000002
+MSFT = "Microsoft"
+StdMfg = "(Standard system devices)"
+DiskId1 = "WDF Sample Toaster Installation Disk #1"
+Toaster.DeviceDesc = "Sample UMDF Toaster Driver - featured"
+Toaster.SVCDESC = "Sample WDF Toaster Service"
+ClassName = "Toaster"
+WudfRdDisplayName="Windows Driver Foundation - User-mode Driver Framework Reflector"
+
diff --git a/general/toaster/umdf2/func/featured/wdffeaturedum.vcxproj b/general/toaster/umdf2/func/featured/wdffeaturedum.vcxproj
new file mode 100644
index 00000000..1af04c81
--- /dev/null
+++ b/general/toaster/umdf2/func/featured/wdffeaturedum.vcxproj
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{99A6009E-6137-462F-89C4-6931045895B1}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{3E5FB5B1-CA59-4675-AAF8-93039F74CF02}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems">
+ <Inf Include=".\wdffeaturedum.inx">
+ <Architecture>$(InfArch)</Architecture>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <CopyOutput>.\$(IntDir)\wdffeaturedum.inf</CopyOutput>
+ </Inf>
+ </ItemGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>wdffeaturedum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>wdffeaturedum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>wdffeaturedum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>wdffeaturedum</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="power.c" />
+ <ClCompile Include="toaster.c" />
+ <ResourceCompile Include="toaster.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/func/featured/wdffeaturedum.vcxproj.Filters b/general/toaster/umdf2/func/featured/wdffeaturedum.vcxproj.Filters
new file mode 100644
index 00000000..ad344822
--- /dev/null
+++ b/general/toaster/umdf2/func/featured/wdffeaturedum.vcxproj.Filters
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{180B07F2-6C79-44F0-9765-749A2975BA1F}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{025585BB-48DE-4F3B-A929-D58821892D58}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{A90CE102-D7E8-46E0-B8D8-D1A57A6CDE82}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{20EB3DBD-A818-46EE-A8B4-6A507F202B60}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include=".\Debug\\wdffeaturedum.inf">
+ <Filter>Driver Files</Filter>
+ </FilesToPackage>
+ <Inf Include=".\wdffeaturedum.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="power.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="toaster.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="toaster.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/func/shared/toaster.h b/general/toaster/umdf2/func/shared/toaster.h
new file mode 100644
index 00000000..006166e7
--- /dev/null
+++ b/general/toaster/umdf2/func/shared/toaster.h
@@ -0,0 +1,118 @@
+/*++
+
+Copyright (c) 1990-2000 Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ Toaster.h
+
+Abstract:
+
+ Header file for the toaster driver modules.
+
+Environment:
+
+ User mode
+
+--*/
+
+
+#if !defined(_TOASTER_H_)
+#define _TOASTER_H_
+
+#include <windows.h>
+#include <winioctl.h>
+#pragma warning( disable: 4201 ) // nonstandard extension used : nameless struct/union
+#include <ntstatus.h>
+#include <devpropdef.h>
+#include <wudfwdm.h>
+#include <wdf.h>
+#include <initguid.h>
+#include "..\inc\driver.h"
+#include "..\inc\public.h"
+
+#define TOASTER_POOL_TAG (ULONG) 'saoT'
+
+//
+// The device extension for the device object
+//
+typedef struct _FDO_DATA
+{
+
+ WDFWMIINSTANCE WmiDeviceArrivalEvent;
+
+ BOOLEAN WmiPowerDeviceEnableRegistered;
+
+} FDO_DATA, *PFDO_DATA;
+
+WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(FDO_DATA, ToasterFdoGetData)
+
+
+//
+// Connector Types
+//
+
+#define TOASTER_WMI_STD_I8042 0
+#define TOASTER_WMI_STD_SERIAL 1
+#define TOASTER_WMI_STD_PARALEL 2
+#define TOASTER_WMI_STD_USB 3
+
+DRIVER_INITIALIZE DriverEntry;
+
+EVT_WDF_DRIVER_DEVICE_ADD ToasterEvtDeviceAdd;
+
+EVT_WDF_DEVICE_CONTEXT_CLEANUP ToasterEvtDeviceContextCleanup;
+EVT_WDF_DEVICE_D0_ENTRY ToasterEvtDeviceD0Entry;
+EVT_WDF_DEVICE_D0_EXIT ToasterEvtDeviceD0Exit;
+EVT_WDF_DEVICE_PREPARE_HARDWARE ToasterEvtDevicePrepareHardware;
+EVT_WDF_DEVICE_RELEASE_HARDWARE ToasterEvtDeviceReleaseHardware;
+
+EVT_WDF_DEVICE_SELF_MANAGED_IO_INIT ToasterEvtDeviceSelfManagedIoInit;
+
+//
+// Io events callbacks.
+//
+EVT_WDF_IO_QUEUE_IO_READ ToasterEvtIoRead;
+EVT_WDF_IO_QUEUE_IO_WRITE ToasterEvtIoWrite;
+EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL ToasterEvtIoDeviceControl;
+EVT_WDF_DEVICE_FILE_CREATE ToasterEvtDeviceFileCreate;
+EVT_WDF_FILE_CLOSE ToasterEvtFileClose;
+
+NTSTATUS
+ToasterWmiRegistration(
+ _In_ WDFDEVICE Device
+ );
+
+//
+// Power events callbacks
+//
+EVT_WDF_DEVICE_ARM_WAKE_FROM_S0 ToasterEvtDeviceArmWakeFromS0;
+EVT_WDF_DEVICE_ARM_WAKE_FROM_SX ToasterEvtDeviceArmWakeFromSx;
+EVT_WDF_DEVICE_DISARM_WAKE_FROM_S0 ToasterEvtDeviceDisarmWakeFromS0;
+EVT_WDF_DEVICE_DISARM_WAKE_FROM_SX ToasterEvtDeviceDisarmWakeFromSx;
+EVT_WDF_DEVICE_WAKE_FROM_S0_TRIGGERED ToasterEvtDeviceWakeFromS0Triggered;
+EVT_WDF_DEVICE_WAKE_FROM_SX_TRIGGERED ToasterEvtDeviceWakeFromSxTriggered;
+
+PCHAR
+DbgDevicePowerString(
+ IN WDF_POWER_DEVICE_STATE Type
+ );
+
+//
+// WMI event callbacks
+//
+EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiInstanceStdDeviceDataQueryInstance;
+EVT_WDF_WMI_INSTANCE_QUERY_INSTANCE EvtWmiInstanceToasterControlQueryInstance;
+EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiInstanceStdDeviceDataSetInstance;
+EVT_WDF_WMI_INSTANCE_SET_INSTANCE EvtWmiInstanceToasterControlSetInstance;
+EVT_WDF_WMI_INSTANCE_SET_ITEM EvtWmiInstanceToasterControlSetItem;
+EVT_WDF_WMI_INSTANCE_SET_ITEM EvtWmiInstanceStdDeviceDataSetItem;
+EVT_WDF_WMI_INSTANCE_EXECUTE_METHOD EvtWmiInstanceToasterControlExecuteMethod;
+
+NTSTATUS
+ToasterFireArrivalEvent(
+ _In_ WDFDEVICE Device
+ );
+
+#endif // _TOASTER_H_
+
diff --git a/general/toaster/umdf2/func/simple/toaster.c b/general/toaster/umdf2/func/simple/toaster.c
new file mode 100644
index 00000000..6ed215db
--- /dev/null
+++ b/general/toaster/umdf2/func/simple/toaster.c
@@ -0,0 +1,418 @@
+/*++
+
+Copyright (c) Microsoft Corporation. All rights reserved.
+
+ THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+ PURPOSE.
+
+Module Name:
+
+ Toaster.c
+
+Abstract:
+
+ This is a simple form of function driver for toaster device. The driver
+ doesn't handle any PnP and Power events because the framework provides
+ default behavior for those events. This driver has enough support to
+ allow an user application (toast/notify.exe) to open the device
+ interface registered by the driver and send read, write or ioctl requests.
+
+Environment:
+
+ Kernel mode
+
+--*/
+
+#include "toaster.h"
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text (INIT, DriverEntry)
+#pragma alloc_text (PAGE, ToasterEvtDeviceAdd)
+#pragma alloc_text (PAGE, ToasterEvtIoRead)
+#pragma alloc_text (PAGE, ToasterEvtIoWrite)
+#pragma alloc_text (PAGE, ToasterEvtIoDeviceControl)
+#endif
+
+
+NTSTATUS
+DriverEntry(
+ IN PDRIVER_OBJECT DriverObject,
+ IN PUNICODE_STRING RegistryPath
+ )
+/*++
+
+Routine Description:
+ DriverEntry initializes the driver and is the first routine called by the
+ system after the driver is loaded. DriverEntry configures and creates a WDF driver
+ object.
+ .
+Parameters Description:
+
+ DriverObject - represents the instance of the function driver that is loaded
+ into memory. DriverObject is allocated by the system before the
+ driver is loaded, and it is released by the system after the system unloads
+ the function driver from memory.
+
+ RegistryPath - represents the driver specific path in the Registry.
+ The function driver can use the path to store driver related data between
+ reboots. The path does not store hardware instance specific data.
+
+Return Value:
+
+ STATUS_SUCCESS if successful,
+ STATUS_UNSUCCESSFUL otherwise.
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ WDF_DRIVER_CONFIG config;
+
+ KdPrint(("Toaster Function Driver Sample - Driver Framework Edition.\n"));
+
+ //
+ // Initiialize driver config to control the attributes that
+ // are global to the driver. Note that framework by default
+ // provides a driver unload routine. If DriverEntry creates any resources
+ // that require clean-up in driver unload,
+ // you can manually override the default by supplying a pointer to the EvtDriverUnload
+ // callback in the config structure. In general xxx_CONFIG_INIT macros are provided to
+ // initialize most commonly used members.
+ //
+
+ WDF_DRIVER_CONFIG_INIT(
+ &config,
+ ToasterEvtDeviceAdd
+ );
+
+
+ //
+ // Create a framework driver object to represent our driver.
+ //
+ status = WdfDriverCreate(
+ DriverObject,
+ RegistryPath,
+ WDF_NO_OBJECT_ATTRIBUTES, // Driver Attributes
+ &config, // Driver Config Info
+ WDF_NO_HANDLE
+ );
+
+ if (!NT_SUCCESS(status)) {
+ KdPrint( ("WdfDriverCreate failed with status 0x%x\n", status));
+ }
+
+ return status;
+}
+
+
+NTSTATUS
+ToasterEvtDeviceAdd(
+ IN WDFDRIVER Driver,
+ IN PWDFDEVICE_INIT DeviceInit
+ )
+/*++
+Routine Description:
+
+ ToasterEvtDeviceAdd is called by the framework in response to AddDevice
+ call from the PnP manager. We create and initialize a WDF device object to
+ represent a new instance of toaster device.
+
+Arguments:
+
+ Driver - Handle to a framework driver object created in DriverEntry
+
+ DeviceInit - Pointer to a framework-allocated WDFDEVICE_INIT structure.
+
+Return Value:
+
+ NTSTATUS
+
+--*/
+{
+ NTSTATUS status = STATUS_SUCCESS;
+ PFDO_DATA fdoData;
+ WDF_IO_QUEUE_CONFIG queueConfig;
+ WDF_OBJECT_ATTRIBUTES fdoAttributes;
+ WDFDEVICE hDevice;
+ WDFQUEUE queue;
+
+ UNREFERENCED_PARAMETER(Driver);
+
+ PAGED_CODE();
+
+ KdPrint(("ToasterEvtDeviceAdd called\n"));
+
+ //
+ // Initialize attributes and a context area for the device object.
+ //
+ //
+ WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&fdoAttributes, FDO_DATA);
+
+ //
+ // Create a framework device object.This call will in turn create
+ // a WDM device object, attach to the lower stack, and set the
+ // appropriate flags and attributes.
+ //
+ status = WdfDeviceCreate(&DeviceInit, &fdoAttributes, &hDevice);
+ if (!NT_SUCCESS(status)) {
+ KdPrint( ("WdfDeviceCreate failed with status code 0x%x\n", status));
+ return status;
+ }
+
+ //
+ // Get the device context by using the accessor function specified in
+ // the WDF_DECLARE_CONTEXT_TYPE_WITH_NAME macro for FDO_DATA.
+ //
+ fdoData = ToasterFdoGetData(hDevice);
+
+ //
+ // Tell the Framework that this device will need an interface
+ //
+ status = WdfDeviceCreateDeviceInterface(
+ hDevice,
+ (LPGUID) &GUID_DEVINTERFACE_TOASTER,
+ NULL // ReferenceString
+ );
+
+ if (!NT_SUCCESS (status)) {
+ KdPrint( ("WdfDeviceCreateDeviceInterface failed 0x%x\n", status));
+ return status;
+ }
+
+ //
+ // Register I/O callbacks to tell the framework that you are interested
+ // in handling IRP_MJ_READ, IRP_MJ_WRITE, and IRP_MJ_DEVICE_CONTROL requests.
+ // If a specific callback function is not specified for one ofthese,
+ // the request will be dispatched to the EvtIoDefault handler, if any.
+ // If there is no EvtIoDefault handler, the request will be failed with
+ // STATUS_INVALID_DEVICE_REQUEST.
+ // WdfIoQueueDispatchParallel means that we are capable of handling
+ // all the I/O requests simultaneously and we are responsible for protecting
+ // data that could be accessed by these callbacks simultaneously.
+ // A default queue gets all the requests that are not
+ // configured for forwarding using WdfDeviceConfigureRequestDispatching.
+ //
+ WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchParallel);
+
+ queueConfig.EvtIoRead = ToasterEvtIoRead;
+ queueConfig.EvtIoWrite = ToasterEvtIoWrite;
+ queueConfig.EvtIoDeviceControl = ToasterEvtIoDeviceControl;
+
+ //
+ // By default, Static Driver Verifier (SDV) displays a warning if it
+ // doesn't find the EvtIoStop callback on a power-managed queue.
+ // The 'assume' below causes SDV to suppress this warning. If the driver
+ // has not explicitly set PowerManaged to WdfFalse, the framework creates
+ // power-managed queues when the device is not a filter driver. Normally
+ // the EvtIoStop is required for power-managed queues, but for this driver
+ // it is not needed b/c the driver doesn't hold on to the requests or
+ // forward them to other drivers. This driver completes the requests
+ // directly in the queue's handlers. If the EvtIoStop callback is not
+ // implemented, the framework waits for all driver-owned requests to be
+ // done before moving in the Dx/sleep states or before removing the
+ // device, which is the correct behavior for this type of driver.
+ // If the requests were taking an indeterminate amount of time to complete,
+ // or if the driver forwarded the requests to a lower driver/another stack,
+ // the queue should have an EvtIoStop/EvtIoResume.
+ //
+ __analysis_assume(queueConfig.EvtIoStop != 0);
+ status = WdfIoQueueCreate(
+ hDevice,
+ &queueConfig,
+ WDF_NO_OBJECT_ATTRIBUTES,
+ &queue
+ );
+ __analysis_assume(queueConfig.EvtIoStop == 0);
+
+ if (!NT_SUCCESS (status)) {
+
+ KdPrint( ("WdfIoQueueCreate failed 0x%x\n", status));
+ return status;
+ }
+
+ return status;
+}
+
+VOID
+ToasterEvtIoRead (
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t Length
+ )
+/*++
+
+Routine Description:
+
+ Performs read from the toaster device. This event is called when the
+ framework receives IRP_MJ_READ requests.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated with the
+ I/O request.
+ Request - Handle to a framework request object.
+
+ Lenght - Length of the data buffer associated with the request.
+ By default, the queue does not dispatch
+ zero length read & write requests to the driver and instead to
+ complete such requests with status success. So we will never get
+ a zero length request.
+
+Return Value:
+
+ None.
+
+--*/
+{
+ NTSTATUS status;
+ ULONG_PTR bytesCopied =0;
+ WDFMEMORY memory;
+
+ UNREFERENCED_PARAMETER(Queue);
+ UNREFERENCED_PARAMETER(Length);
+
+ PAGED_CODE();
+
+ KdPrint(( "ToasterEvtIoRead: Request: 0x%p, Queue: 0x%p\n",
+ Request, Queue));
+
+ //
+ // Get the request memory and perform read operation here
+ //
+ status = WdfRequestRetrieveOutputMemory(Request, &memory);
+ if(NT_SUCCESS(status) ) {
+ //
+ // Copy data into the memory buffer using WdfMemoryCopyFromBuffer
+ //
+ }
+
+ WdfRequestCompleteWithInformation(Request, status, bytesCopied);
+}
+
+VOID
+ToasterEvtIoWrite (
+ WDFQUEUE Queue,
+ WDFREQUEST Request,
+ size_t Length
+ )
+/*++
+
+Routine Description:
+
+ Performs write to the toaster device. This event is called when the
+ framework receives IRP_MJ_WRITE requests.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated with the
+ I/O request.
+ Request - Handle to a framework request object.
+
+ Lenght - Length of the data buffer associated with the request.
+ The default property of the queue is to not dispatch
+ zero lenght read & write requests to the driver and
+ complete is with status success. So we will never get
+ a zero length request.
+
+Return Value:
+
+ None
+--*/
+
+{
+ NTSTATUS status;
+ ULONG_PTR bytesWritten =0;
+ WDFMEMORY memory;
+
+ UNREFERENCED_PARAMETER(Queue);
+ UNREFERENCED_PARAMETER(Length);
+
+ KdPrint(("ToasterEvtIoWrite. Request: 0x%p, Queue: 0x%p\n",
+ Request, Queue));
+
+ PAGED_CODE();
+
+ //
+ // Get the request buffer and perform write operation here
+ //
+ status = WdfRequestRetrieveInputMemory(Request, &memory);
+ if(NT_SUCCESS(status) ) {
+ //
+ // 1) Use WdfMemoryCopyToBuffer to copy data from the request
+ // to driver buffer.
+ // 2) Or get the buffer pointer from the request by calling
+ // WdfRequestRetrieveInputBuffer
+ // 3) Or you can get the buffer pointer from the memory handle
+ // by calling WdfMemoryGetBuffer.
+ //
+ bytesWritten = Length;
+ }
+
+ WdfRequestCompleteWithInformation(Request, status, bytesWritten);
+
+}
+
+
+VOID
+ToasterEvtIoDeviceControl(
+ IN WDFQUEUE Queue,
+ IN WDFREQUEST Request,
+ IN size_t OutputBufferLength,
+ IN size_t InputBufferLength,
+ IN ULONG IoControlCode
+ )
+/*++
+Routine Description:
+
+ This event is called when the framework receives IRP_MJ_DEVICE_CONTROL
+ requests from the system.
+
+Arguments:
+
+ Queue - Handle to the framework queue object that is associated
+ with the I/O request.
+ Request - Handle to a framework request object.
+
+ OutputBufferLength - length of the request's output buffer,
+ if an output buffer is available.
+ InputBufferLength - length of the request's input buffer,
+ if an input buffer is available.
+
+ IoControlCode - the driver-defined or system-defined I/O control code
+ (IOCTL) that is associated with the request.
+
+Return Value:
+
+ VOID
+
+--*/
+{
+ NTSTATUS status= STATUS_SUCCESS;
+
+ UNREFERENCED_PARAMETER(Queue);
+ UNREFERENCED_PARAMETER(OutputBufferLength);
+ UNREFERENCED_PARAMETER(InputBufferLength);
+
+ KdPrint(("ToasterEvtIoDeviceControl called\n"));
+
+ PAGED_CODE();
+
+ //
+ // Use WdfRequestRetrieveInputBuffer and WdfRequestRetrieveOutputBuffer
+ // to get the request buffers.
+ //
+
+ switch (IoControlCode) {
+
+ default:
+ status = STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ //
+ // Complete the Request.
+ //
+ WdfRequestCompleteWithInformation(Request, status, (ULONG_PTR) 0);
+}
+
+
diff --git a/general/toaster/umdf2/func/simple/wdfsimpleum.inx b/general/toaster/umdf2/func/simple/wdfsimpleum.inx
new file mode 100644
index 00000000..6edb9388
--- /dev/null
+++ b/general/toaster/umdf2/func/simple/wdfsimpleum.inx
@@ -0,0 +1,97 @@
+;/*++
+;
+;Copyright (c) Microsoft Corporation. All rights reserved.
+;
+;Module Name:
+; wdfsimpleum.INF
+;
+;Abstract:
+; INF file for installing the UMDF2 Toaster Driver
+;
+;Installation Notes:
+; Using Devcon: Type "devcon install wdfsimpleum.inf root\toaster" to install
+;
+;--*/
+
+[Version]
+Signature="$WINDOWS NT$"
+Class=TOASTER
+ClassGuid={B85B7C50-6A01-11d2-B841-00C04FAD5171}
+Provider=%MSFT%
+DriverVer=03/20/2003,5.00.3788
+CatalogFile=wudf.cat
+
+[DestinationDirs]
+DefaultDestDir = 12
+
+; ================= Class section =====================
+
+[ClassInstall32]
+Addreg=ToasterClassReg
+
+[ToasterClassReg]
+HKR,,,0,%ClassName%
+HKR,,Icon,,100
+HKR,,DeviceCharacteristics,0x10001,0x100 ;Use same security checks on relative opens
+HKR,,Security,,"D:P(A;;GA;;;SY)(A;;GA;;;BA)" ;Allow generic all access to system and built-in Admin.
+ ;This one overrides the security set by the driver
+
+[SourceDisksNames]
+1 = %DiskId1%,,,""
+
+[SourceDisksFiles]
+wdfsimpleum.dll = 1,,
+
+;*****************************************
+; Toaster Install Section
+;*****************************************
+
+[Manufacturer]
+%StdMfg%=Standard,NT$ARCH$
+
+;
+; Hw Id is root\toaster
+;
+[Standard.NT$ARCH$]
+%Toaster.DeviceDesc%=Toaster_Device, root\toaster
+
+;---------------- copy files
+
+[Toaster_Device.NT]
+CopyFiles=UMDriverCopy
+
+[UMDriverCopy]
+wdfsimpleum.dll,,,0x00004000 ; COPYFLG_IN_USE_RENAME
+
+[DestinationDirs]
+UMDriverCopy=12,UMDF ; copy to drivers\umdf
+
+;-------------- Service installation
+[Toaster_Device.NT.Services]
+AddService=WUDFRd,0x000001fa,WUDFRD_ServiceInstall
+
+[WUDFRD_ServiceInstall]
+DisplayName = %WudfRdDisplayName%
+ServiceType = 1
+StartType = 3
+ErrorControl = 1
+ServiceBinary = %12%\WUDFRd.sys
+
+;-------------- WDF specific section -------------
+[Toaster_Device.NT.Wdf]
+UmdfService=wdfsimpleum, Toaster_Install
+UmdfServiceOrder=wdfsimpleum
+
+[Toaster_Install]
+UmdfLibraryVersion=$UMDFVERSION$
+ServiceBinary=%12%\UMDF\wdfsimpleum.dll
+
+[Strings]
+SPSVCINST_ASSOCSERVICE= 0x00000002
+MSFT = "Microsoft"
+StdMfg = "(Standard system devices)"
+DiskId1 = "WDF Sample Toaster Installation Disk #1"
+Toaster.DeviceDesc = "Sample UMDF Toaster Driver - simple"
+ClassName = "Toaster"
+WudfRdDisplayName="Windows Driver Foundation - User-mode Driver Framework Reflector"
+
diff --git a/general/toaster/umdf2/func/simple/wdfsimpleum.vcxproj b/general/toaster/umdf2/func/simple/wdfsimpleum.vcxproj
new file mode 100644
index 00000000..5420719a
--- /dev/null
+++ b/general/toaster/umdf2/func/simple/wdfsimpleum.vcxproj
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{4867F54B-D8EF-45B0-984E-D571D987174A}</ProjectGuid>
+ <RootNamespace>$(MSBuildProjectName)</RootNamespace>
+ <UMDF_VERSION_MAJOR>2</UMDF_VERSION_MAJOR>
+ <SupportsPackaging>false</SupportsPackaging>
+ <RequiresPackageProject>true</RequiresPackageProject>
+ <Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
+ <Platform Condition="'$(Platform)' == ''">Win32</Platform>
+ <SampleGuid>{04436AEB-A589-41DD-A088-A1503096D2D8}</SampleGuid>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>False</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetVersion>Windows10</TargetVersion>
+ <UseDebugLibraries>True</UseDebugLibraries>
+ <DriverTargetPlatform>Universal</DriverTargetPlatform>
+ <DriverType>UMDF</DriverType>
+ <PlatformToolset>WindowsUserModeDriver10.0</PlatformToolset>
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <PropertyGroup>
+ <OutDir>$(IntDir)</OutDir>
+ </PropertyGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
+ </ImportGroup>
+ <ItemGroup Label="WrappedTaskItems">
+ <Inf Include=".\wdfsimpleum.inx">
+ <Architecture>$(InfArch)</Architecture>
+ <SpecifyArchitecture>true</SpecifyArchitecture>
+ <CopyOutput>.\$(IntDir)\wdfsimpleum.inf</CopyOutput>
+ </Inf>
+ </ItemGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <TargetName>wdfsimpleum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <TargetName>wdfsimpleum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <TargetName>wdfsimpleum</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <TargetName>wdfsimpleum</TargetName>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Link>
+ <AdditionalDependencies>%(AdditionalDependencies);$(SDK_LIB_PATH)\mincore.lib</AdditionalDependencies>
+ </Link>
+ <ResourceCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </ResourceCompile>
+ <ClCompile>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ <ExceptionHandling>
+ </ExceptionHandling>
+ </ClCompile>
+ <Midl>
+ <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);..\..\inc;..\shared</AdditionalIncludeDirectories>
+ </Midl>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="toaster.c" />
+ </ItemGroup>
+ <ItemGroup>
+ <Inf Exclude="@(Inf)" Include="*.inf" />
+ <FilesToPackage Include="$(TargetPath)" Condition="'$(ConfigurationType)'=='Driver' or '$(ConfigurationType)'=='DynamicLibrary'" />
+ <FilesToPackage Include="@(Inf->'%(CopyOutput)')" Condition="'@(Inf)'!=''" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Exclude="@(None)" Include="*.txt;*.htm;*.html" />
+ <None Exclude="@(None)" Include="*.ico;*.cur;*.bmp;*.dlg;*.rct;*.gif;*.jpg;*.jpeg;*.wav;*.jpe;*.tiff;*.tif;*.png;*.rc2" />
+ <None Exclude="@(None)" Include="*.def;*.bat;*.hpj;*.asmx" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Exclude="@(ClInclude)" Include="*.h;*.hpp;*.hxx;*.hm;*.inl;*.xsd" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/func/simple/wdfsimpleum.vcxproj.Filters b/general/toaster/umdf2/func/simple/wdfsimpleum.vcxproj.Filters
new file mode 100644
index 00000000..6054e358
--- /dev/null
+++ b/general/toaster/umdf2/func/simple/wdfsimpleum.vcxproj.Filters
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;*</Extensions>
+ <UniqueIdentifier>{00F8EE65-92A7-4127-B44C-E8F26A2136D5}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Header Files">
+ <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ <UniqueIdentifier>{77C5B494-74A7-4FE1-97B8-0B859BE75D43}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Resource Files">
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms;man;xml</Extensions>
+ <UniqueIdentifier>{9769E294-A7B6-4585-9CA6-AFDEA3DCA9F4}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Driver Files">
+ <Extensions>inf;inv;inx;mof;mc;</Extensions>
+ <UniqueIdentifier>{18744B3D-F47A-476E-9BF7-FE6592698961}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <FilesToPackage Include=".\Debug\\wdfsimpleum.inf">
+ <Filter>Driver Files</Filter>
+ </FilesToPackage>
+ <Inf Include=".\wdfsimpleum.inx">
+ <Filter>Driver Files</Filter>
+ </Inf>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="toaster.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/general/toaster/umdf2/inc/driver.h b/general/toaster/umdf2/inc/driver.h
new file mode 100644
index 00000000..b1073363
--- /dev/null
+++ b/general/toaster/umdf2/inc/driver.h
@@ -0,0 +1,69 @@
+/*++
+Copyright (c) 1990-2000 Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ driver.h
+
+Abstract:
+
+ This module contains the common declarations for the
+ bus, function and filter drivers.
+
+Environment:
+
+ kernel mode only
+
+--*/
+
+//#include "public.h"
+
+//
+// Define an Interface Guid to access the proprietary toaster interface.
+// This guid is used to identify a specific interface in IRP_MN_QUERY_INTERFACE
+// handler.
+//
+
+DEFINE_GUID(GUID_TOASTER_INTERFACE_STANDARD,
+ 0xe0b27630, 0x5434, 0x11d3, 0xb8, 0x90, 0x0, 0xc0, 0x4f, 0xad, 0x51, 0x71);
+// {E0B27630-5434-11d3-B890-00C04FAD5171}
+
+
+//
+// GUID definition are required to be outside of header inclusion pragma to avoid
+// error during precompiled headers.
+//
+
+#ifndef __DRIVER_H
+#define __DRIVER_H
+
+//
+// Define Interface reference/dereference routines for
+// Interfaces exported by IRP_MN_QUERY_INTERFACE
+//
+
+typedef VOID (*PINTERFACE_REFERENCE)(PVOID Context);
+typedef VOID (*PINTERFACE_DEREFERENCE)(PVOID Context);
+
+typedef
+BOOLEAN
+(*PTOASTER_GET_CRISPINESS_LEVEL)(
+ IN PVOID Context,
+ OUT PUCHAR Level
+ );
+
+typedef
+BOOLEAN
+(*PTOASTER_SET_CRISPINESS_LEVEL)(
+ IN PVOID Context,
+ OUT UCHAR Level
+ );
+
+typedef
+BOOLEAN
+(*PTOASTER_IS_CHILD_PROTECTED)(
+ IN PVOID Context
+ );
+
+#endif
+
diff --git a/general/toaster/umdf2/inc/public.h b/general/toaster/umdf2/inc/public.h
new file mode 100644
index 00000000..0628f95f
--- /dev/null
+++ b/general/toaster/umdf2/inc/public.h
@@ -0,0 +1,167 @@
+/*++
+Copyright (c) 1990-2000 Microsoft Corporation All Rights Reserved
+
+Module Name:
+
+ public.h
+
+Abstract:
+
+ This module contains the common declarations shared by driver
+ and user applications.
+
+Environment:
+
+ user and kernel
+
+--*/
+
+//
+// Define an Interface Guid for bus enumerator class.
+// This GUID is used to register (IoRegisterDeviceInterface)
+// an instance of an interface so that enumerator application
+// can send an ioctl to the bus driver.
+//
+
+DEFINE_GUID (GUID_DEVINTERFACE_BUSENUM_TOASTER,
+ 0xD35F7840, 0x6A0C, 0x11d2, 0xB8, 0x41, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71);
+// {D35F7840-6A0C-11d2-B841-00C04FAD5171}
+
+//
+// Define an Interface Guid for toaster device class.
+// This GUID is used to register (IoRegisterDeviceInterface)
+// an instance of an interface so that user application
+// can control the toaster device.
+//
+
+DEFINE_GUID (GUID_DEVINTERFACE_TOASTER,
+ 0x781EF630, 0x72B2, 0x11d2, 0xB8, 0x52, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71);
+//{781EF630-72B2-11d2-B852-00C04FAD5171}
+
+//
+// Define a Setup Class GUID for Toaster Class. This is same
+// as the TOASTSER CLASS guid in the INF files.
+//
+
+DEFINE_GUID (GUID_DEVCLASS_TOASTER,
+ 0xB85B7C50, 0x6A01, 0x11d2, 0xB8, 0x41, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71);
+//{B85B7C50-6A01-11d2-B841-00C04FAD5171}
+
+//
+// Define a WMI GUID to get busenum info.
+//
+
+DEFINE_GUID (TOASTER_BUS_WMI_STD_DATA_GUID,
+ 0x0006A660, 0x8F12, 0x11d2, 0xB8, 0x54, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71);
+//{0006A660-8F12-11d2-B854-00C04FAD5171}
+
+//
+// Define a WMI GUID to get toaster device info.
+//
+
+DEFINE_GUID (TOASTER_WMI_STD_DATA_GUID,
+ 0xBBA21300L, 0x6DD3, 0x11d2, 0xB8, 0x44, 0x00, 0xC0, 0x4F, 0xAD, 0x51, 0x71);
+
+//
+// Define a WMI GUID to represent device arrival notification WMIEvent class.
+//
+
+DEFINE_GUID (TOASTER_NOTIFY_DEVICE_ARRIVAL_EVENT,
+ 0x1cdaff1, 0xc901, 0x45b4, 0xb3, 0x59, 0xb5, 0x54, 0x27, 0x25, 0xe2, 0x9c);
+// {01CDAFF1-C901-45b4-B359-B5542725E29C}
+
+
+//
+// GUID definition are required to be outside of header inclusion pragma to avoid
+// error during precompiled headers.
+//
+
+#ifndef __PUBLIC_H
+#define __PUBLIC_H
+
+#define BUS_HARDWARE_IDS L"{B85B7C50-6A01-11d2-B841-00C04FAD5171}\\MsToaster\0"
+#define BUS_HARDWARE_IDS_LENGTH sizeof (BUS_HARDWARE_IDS)
+
+#define BUSENUM_COMPATIBLE_IDS L"{B85B7C50-6A01-11d2-B841-00C04FAD5171}\\MsCompatibleToaster\0"
+#define BUSENUM_COMPATIBLE_IDS_LENGTH sizeof(BUSENUM_COMPATIBLE_IDS)
+
+
+#define FILE_DEVICE_BUSENUM FILE_DEVICE_BUS_EXTENDER
+
+#define BUSENUM_IOCTL(_index_) \
+ CTL_CODE (FILE_DEVICE_BUSENUM, _index_, METHOD_BUFFERED, FILE_READ_DATA)
+
+#define IOCTL_BUSENUM_PLUGIN_HARDWARE BUSENUM_IOCTL (0x0)
+#define IOCTL_BUSENUM_UNPLUG_HARDWARE BUSENUM_IOCTL (0x1)
+#define IOCTL_BUSENUM_EJECT_HARDWARE BUSENUM_IOCTL (0x2)
+#define IOCTL_TOASTER_DONT_DISPLAY_IN_UI_DEVICE BUSENUM_IOCTL (0x3)
+
+//
+// Data structure used in PlugIn and UnPlug ioctls
+//
+
+typedef struct _BUSENUM_PLUGIN_HARDWARE
+{
+ //
+ // sizeof (struct _BUSENUM_HARDWARE)
+ //
+ IN ULONG Size;
+
+ //
+ // Unique serial number of the device to be enumerated.
+ // Enumeration will be failed if another device on the
+ // bus has the same serail number.
+ //
+
+ IN ULONG SerialNo;
+
+ //
+ // An array of (zero terminated wide character strings). The array itself
+ // also null terminated (ie, MULTI_SZ)
+ //
+ #pragma warning(disable:4200) // nonstandard extension used
+
+ IN WCHAR HardwareIDs[];
+
+ #pragma warning(default:4200)
+
+} BUSENUM_PLUGIN_HARDWARE, *PBUSENUM_PLUGIN_HARDWARE;
+
+typedef struct _BUSENUM_UNPLUG_HARDWARE
+{
+ //
+ // sizeof (struct _REMOVE_HARDWARE)
+ //
+
+ IN ULONG Size;
+
+ //
+ // Serial number of the device to be plugged out
+ //
+
+ ULONG SerialNo;
+
+ ULONG Reserved[2];
+
+} BUSENUM_UNPLUG_HARDWARE, *PBUSENUM_UNPLUG_HARDWARE;
+
+typedef struct _BUSENUM_EJECT_HARDWARE
+{
+ //
+ // sizeof (struct _EJECT_HARDWARE)
+ //
+
+ IN ULONG Size;
+
+ //
+ // Serial number of the device to be ejected
+ //
+
+ ULONG SerialNo;
+
+ ULONG Reserved[2];
+
+} BUSENUM_EJECT_HARDWARE, *PBUSENUM_EJECT_HARDWARE;
+
+#endif
+
diff --git a/general/toaster/umdf2/umdf2toaster.sln b/general/toaster/umdf2/umdf2toaster.sln
new file mode 100644
index 00000000..27a7c11c
--- /dev/null
+++ b/general/toaster/umdf2/umdf2toaster.sln
@@ -0,0 +1,123 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0
+MinimumVisualStudioVersion = 12.0
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Package", "Package", "{DE39E506-CDA6-472B-AA38-CFD787389792}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Notify", "Notify", "{6A99D8D7-8707-44E7-8952-C08DA9607026}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Exe", "Exe", "{812F37C3-6174-45B1-BAE8-8A1D22588B5A}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Toast", "Toast", "{C76A23DC-DCC1-457B-A57C-FC050E0E28E0}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Enum", "Enum", "{29F16893-9AB9-45AC-AF5B-4E933C2E6A95}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Simple", "Simple", "{5652F0ED-6624-49EC-9DB9-B5A3F7253FA3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Func", "Func", "{2C164544-0A50-43A5-A42C-B7B25D777B4E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Featured", "Featured", "{0213881B-B2CC-453E-BBCA-95EE52FEA9C1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generic", "Generic", "{F2D765A7-8801-482C-924A-0B647DEAE5D5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Filter", "Filter", "{870F719A-95BC-485D-9787-2634A3C2652F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "package", "Package\package.VcxProj", "{52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "notify", "exe\notify\notify.vcxproj", "{FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "toast", "exe\toast\toast.vcxproj", "{9BF4F988-D8B7-4E73-BC77-6658D413212F}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Enum", "exe\enum\Enum.vcxproj", "{6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wdfsimpleum", "func\simple\wdfsimpleum.vcxproj", "{4867F54B-D8EF-45B0-984E-D571D987174A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wdffeaturedum", "func\featured\wdffeaturedum.vcxproj", "{99A6009E-6137-462F-89C4-6931045895B1}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "filterum", "filter\generic\filterum.vcxproj", "{A60F76D2-C512-4DA6-8C80-263F1B506267}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ Debug|x64 = Debug|x64
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}.Debug|Win32.ActiveCfg = Debug|Win32
+ {52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}.Debug|Win32.Build.0 = Debug|Win32
+ {52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}.Release|Win32.ActiveCfg = Release|Win32
+ {52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}.Release|Win32.Build.0 = Release|Win32
+ {52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}.Debug|x64.ActiveCfg = Debug|x64
+ {52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}.Debug|x64.Build.0 = Debug|x64
+ {52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}.Release|x64.ActiveCfg = Release|x64
+ {52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5}.Release|x64.Build.0 = Release|x64
+ {FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}.Debug|Win32.Build.0 = Debug|Win32
+ {FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}.Release|Win32.ActiveCfg = Release|Win32
+ {FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}.Release|Win32.Build.0 = Release|Win32
+ {FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}.Debug|x64.ActiveCfg = Debug|x64
+ {FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}.Debug|x64.Build.0 = Debug|x64
+ {FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}.Release|x64.ActiveCfg = Release|x64
+ {FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76}.Release|x64.Build.0 = Release|x64
+ {9BF4F988-D8B7-4E73-BC77-6658D413212F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {9BF4F988-D8B7-4E73-BC77-6658D413212F}.Debug|Win32.Build.0 = Debug|Win32
+ {9BF4F988-D8B7-4E73-BC77-6658D413212F}.Release|Win32.ActiveCfg = Release|Win32
+ {9BF4F988-D8B7-4E73-BC77-6658D413212F}.Release|Win32.Build.0 = Release|Win32
+ {9BF4F988-D8B7-4E73-BC77-6658D413212F}.Debug|x64.ActiveCfg = Debug|x64
+ {9BF4F988-D8B7-4E73-BC77-6658D413212F}.Debug|x64.Build.0 = Debug|x64
+ {9BF4F988-D8B7-4E73-BC77-6658D413212F}.Release|x64.ActiveCfg = Release|x64
+ {9BF4F988-D8B7-4E73-BC77-6658D413212F}.Release|x64.Build.0 = Release|x64
+ {6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}.Debug|Win32.ActiveCfg = Debug|Win32
+ {6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}.Debug|Win32.Build.0 = Debug|Win32
+ {6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}.Release|Win32.ActiveCfg = Release|Win32
+ {6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}.Release|Win32.Build.0 = Release|Win32
+ {6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}.Debug|x64.ActiveCfg = Debug|x64
+ {6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}.Debug|x64.Build.0 = Debug|x64
+ {6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}.Release|x64.ActiveCfg = Release|x64
+ {6E1593D4-08A1-45E4-A77F-AF34AC6F0D69}.Release|x64.Build.0 = Release|x64
+ {4867F54B-D8EF-45B0-984E-D571D987174A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {4867F54B-D8EF-45B0-984E-D571D987174A}.Debug|Win32.Build.0 = Debug|Win32
+ {4867F54B-D8EF-45B0-984E-D571D987174A}.Release|Win32.ActiveCfg = Release|Win32
+ {4867F54B-D8EF-45B0-984E-D571D987174A}.Release|Win32.Build.0 = Release|Win32
+ {4867F54B-D8EF-45B0-984E-D571D987174A}.Debug|x64.ActiveCfg = Debug|x64
+ {4867F54B-D8EF-45B0-984E-D571D987174A}.Debug|x64.Build.0 = Debug|x64
+ {4867F54B-D8EF-45B0-984E-D571D987174A}.Release|x64.ActiveCfg = Release|x64
+ {4867F54B-D8EF-45B0-984E-D571D987174A}.Release|x64.Build.0 = Release|x64
+ {99A6009E-6137-462F-89C4-6931045895B1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {99A6009E-6137-462F-89C4-6931045895B1}.Debug|Win32.Build.0 = Debug|Win32
+ {99A6009E-6137-462F-89C4-6931045895B1}.Release|Win32.ActiveCfg = Release|Win32
+ {99A6009E-6137-462F-89C4-6931045895B1}.Release|Win32.Build.0 = Release|Win32
+ {99A6009E-6137-462F-89C4-6931045895B1}.Debug|x64.ActiveCfg = Debug|x64
+ {99A6009E-6137-462F-89C4-6931045895B1}.Debug|x64.Build.0 = Debug|x64
+ {99A6009E-6137-462F-89C4-6931045895B1}.Release|x64.ActiveCfg = Release|x64
+ {99A6009E-6137-462F-89C4-6931045895B1}.Release|x64.Build.0 = Release|x64
+ {A60F76D2-C512-4DA6-8C80-263F1B506267}.Debug|Win32.ActiveCfg = Debug|Win32
+ {A60F76D2-C512-4DA6-8C80-263F1B506267}.Debug|Win32.Build.0 = Debug|Win32
+ {A60F76D2-C512-4DA6-8C80-263F1B506267}.Release|Win32.ActiveCfg = Release|Win32
+ {A60F76D2-C512-4DA6-8C80-263F1B506267}.Release|Win32.Build.0 = Release|Win32
+ {A60F76D2-C512-4DA6-8C80-263F1B506267}.Debug|x64.ActiveCfg = Debug|x64
+ {A60F76D2-C512-4DA6-8C80-263F1B506267}.Debug|x64.Build.0 = Debug|x64
+ {A60F76D2-C512-4DA6-8C80-263F1B506267}.Release|x64.ActiveCfg = Release|x64
+ {A60F76D2-C512-4DA6-8C80-263F1B506267}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {52EEA7C4-68B9-4AE9-B3EC-881A49E9E1E5} = {DE39E506-CDA6-472B-AA38-CFD787389792}
+ {FEBBDE46-4BD4-462D-87BD-8FDC8C1ECB76} = {6A99D8D7-8707-44E7-8952-C08DA9607026}
+ {9BF4F988-D8B7-4E73-BC77-6658D413212F} = {C76A23DC-DCC1-457B-A57C-FC050E0E28E0}
+ {6E1593D4-08A1-45E4-A77F-AF34AC6F0D69} = {29F16893-9AB9-45AC-AF5B-4E933C2E6A95}
+ {4867F54B-D8EF-45B0-984E-D571D987174A} = {5652F0ED-6624-49EC-9DB9-B5A3F7253FA3}
+ {99A6009E-6137-462F-89C4-6931045895B1} = {0213881B-B2CC-453E-BBCA-95EE52FEA9C1}
+ {A60F76D2-C512-4DA6-8C80-263F1B506267} = {F2D765A7-8801-482C-924A-0B647DEAE5D5}
+ {6A99D8D7-8707-44E7-8952-C08DA9607026} = {812F37C3-6174-45B1-BAE8-8A1D22588B5A}
+ {C76A23DC-DCC1-457B-A57C-FC050E0E28E0} = {812F37C3-6174-45B1-BAE8-8A1D22588B5A}
+ {29F16893-9AB9-45AC-AF5B-4E933C2E6A95} = {812F37C3-6174-45B1-BAE8-8A1D22588B5A}
+ {5652F0ED-6624-49EC-9DB9-B5A3F7253FA3} = {2C164544-0A50-43A5-A42C-B7B25D777B4E}
+ {0213881B-B2CC-453E-BBCA-95EE52FEA9C1} = {2C164544-0A50-43A5-A42C-B7B25D777B4E}
+ {F2D765A7-8801-482C-924A-0B647DEAE5D5} = {870F719A-95BC-485D-9787-2634A3C2652F}
+ EndGlobalSection
+EndGlobal