summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2018-05-16 23:15:08 +0800
committerruki <[email protected]>2018-05-16 13:30:49 +0800
commit9275981ad07841dad83f07235339efc06dd40af8 (patch)
tree317b78339ad8d88844f4091423d149682e2ad276
parent0e7791da7d897a809ea3922ddc772d700a7b491e (diff)
add sdkver for stampinf and skeleton
-rw-r--r--tests/projects/wdk/umdf/skeleton/Skeleton.rc21
-rw-r--r--tests/projects/wdk/umdf/skeleton/UMDFSkeleton_OSR.inxbin0 -> 5646 bytes
-rw-r--r--tests/projects/wdk/umdf/skeleton/UMDFSkeleton_Root.inxbin0 -> 3798 bytes
-rw-r--r--tests/projects/wdk/umdf/skeleton/comsup.cpp344
-rw-r--r--tests/projects/wdk/umdf/skeleton/comsup.h215
-rw-r--r--tests/projects/wdk/umdf/skeleton/device.cpp238
-rw-r--r--tests/projects/wdk/umdf/skeleton/device.h115
-rw-r--r--tests/projects/wdk/umdf/skeleton/dllsup.cpp177
-rw-r--r--tests/projects/wdk/umdf/skeleton/driver.cpp220
-rw-r--r--tests/projects/wdk/umdf/skeleton/driver.h149
-rw-r--r--tests/projects/wdk/umdf/skeleton/exports.def10
-rw-r--r--tests/projects/wdk/umdf/skeleton/internal.h90
-rw-r--r--tests/projects/wdk/umdf/skeleton/xmake.lua29
-rw-r--r--xmake/rules/wdk/env/xmake.lua23
-rw-r--r--xmake/rules/wdk/inf/xmake.lua24
-rw-r--r--xmake/rules/wdk/load.lua20
16 files changed, 1670 insertions, 5 deletions
diff --git a/tests/projects/wdk/umdf/skeleton/Skeleton.rc b/tests/projects/wdk/umdf/skeleton/Skeleton.rc
new file mode 100644
index 000000000..0e202c4f5
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/Skeleton.rc
@@ -0,0 +1,21 @@
+//---------------------------------------------------------------------------
+// Skeleton.rc
+//
+// Copyright (c) Microsoft Corporation, All Rights Reserved
+//---------------------------------------------------------------------------
+
+
+#include <windows.h>
+#include <ntverp.h>
+
+//
+// TODO: Change the file description and file names to match your binary.
+//
+
+#define VER_FILETYPE VFT_DLL
+#define VER_FILESUBTYPE VFT_UNKNOWN
+#define VER_FILEDESCRIPTION_STR "WDF:UMDF Skeleton User-Mode Driver Sample"
+#define VER_INTERNALNAME_STR "UMDFSkeleton"
+#define VER_ORIGINALFILENAME_STR "UMDFSkeleton.dll"
+
+#include "common.ver"
diff --git a/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_OSR.inx b/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_OSR.inx
new file mode 100644
index 000000000..3da01ae62
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_OSR.inx
Binary files differ
diff --git a/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_Root.inx b/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_Root.inx
new file mode 100644
index 000000000..63d9f94c5
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/UMDFSkeleton_Root.inx
Binary files differ
diff --git a/tests/projects/wdk/umdf/skeleton/comsup.cpp b/tests/projects/wdk/umdf/skeleton/comsup.cpp
new file mode 100644
index 000000000..fb0b0807c
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/comsup.cpp
@@ -0,0 +1,344 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved
+
+Module Name:
+
+ ComSup.cpp
+
+Abstract:
+
+ This module contains implementations for the functions and methods
+ used for providing COM support.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#include "internal.h"
+
+#include "comsup.tmh"
+
+//
+// Implementation of CUnknown methods.
+//
+
+CUnknown::CUnknown(
+ VOID
+ ) : m_ReferenceCount(1)
+/*++
+
+ Routine Description:
+
+ Constructor for an instance of the CUnknown class. This simply initializes
+ the reference count of the object to 1. The caller is expected to
+ call Release() if it wants to delete the object once it has been allocated.
+
+ Arguments:
+
+ None
+
+ Return Value:
+
+ None
+
+--*/
+{
+ // do nothing.
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CUnknown::QueryInterface(
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Object
+ )
+/*++
+
+ Routine Description:
+
+ This method provides the basic support for query interface on CUnknown.
+ If the interface requested is IUnknown it references the object and
+ returns an interface pointer. Otherwise it returns an error.
+
+ Arguments:
+
+ InterfaceId - the IID being requested
+
+ Object - a location to store the interface pointer to return.
+
+ Return Value:
+
+ S_OK or E_NOINTERFACE
+
+--*/
+{
+ if (IsEqualIID(InterfaceId, __uuidof(IUnknown)))
+ {
+ *Object = QueryIUnknown();
+ return S_OK;
+ }
+ else
+ {
+ *Object = NULL;
+ return E_NOINTERFACE;
+ }
+}
+
+IUnknown *
+CUnknown::QueryIUnknown(
+ VOID
+ )
+/*++
+
+ Routine Description:
+
+ This helper method references the object and returns a pointer to the
+ object's IUnknown interface.
+
+ This allows other methods to convert a CUnknown pointer into an IUnknown
+ pointer without a typecast and without calling QueryInterface and dealing
+ with the return value.
+
+ Arguments:
+
+ None
+
+ Return Value:
+
+ A pointer to the object's IUnknown interface.
+
+--*/
+{
+ AddRef();
+ return static_cast<IUnknown *>(this);
+}
+
+ULONG
+STDMETHODCALLTYPE
+CUnknown::AddRef(
+ VOID
+ )
+/*++
+
+ Routine Description:
+
+ This method adds one to the object's reference count.
+
+ Arguments:
+
+ None
+
+ Return Value:
+
+ The new reference count. The caller should only use this for debugging
+ as the object's actual reference count can change while the caller
+ examines the return value.
+
+--*/
+{
+ return InterlockedIncrement(&m_ReferenceCount);
+}
+
+ULONG
+STDMETHODCALLTYPE
+CUnknown::Release(
+ VOID
+ )
+/*++
+
+ Routine Description:
+
+ This method subtracts one to the object's reference count. If the count
+ goes to zero, this method deletes the object.
+
+ Arguments:
+
+ None
+
+ Return Value:
+
+ The new reference count. If the caller uses this value it should only be
+ to check for zero (i.e. this call caused or will cause deletion) or
+ non-zero (i.e. some other call may have caused deletion, but this one
+ didn't).
+
+--*/
+{
+ ULONG count = InterlockedDecrement(&m_ReferenceCount);
+
+ if (count == 0)
+ {
+ delete this;
+ }
+ return count;
+}
+
+//
+// Implementation of CClassFactory methods.
+//
+
+//
+// Define storage for the factory's static lock count variable.
+//
+
+LONG CClassFactory::s_LockCount = 0;
+
+IClassFactory *
+CClassFactory::QueryIClassFactory(
+ VOID
+ )
+/*++
+
+ Routine Description:
+
+ This helper method references the object and returns a pointer to the
+ object's IClassFactory interface.
+
+ This allows other methods to convert a CClassFactory pointer into an
+ IClassFactory pointer without a typecast and without dealing with the
+ return value QueryInterface.
+
+ Arguments:
+
+ None
+
+ Return Value:
+
+ A referenced pointer to the object's IClassFactory interface.
+
+--*/
+{
+ AddRef();
+ return static_cast<IClassFactory *>(this);
+}
+
+HRESULT
+CClassFactory::QueryInterface(
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Object
+ )
+/*++
+
+ Routine Description:
+
+ This method attempts to retrieve the requested interface from the object.
+
+ If the interface is found then the reference count on that interface (and
+ thus the object itself) is incremented.
+
+ Arguments:
+
+ InterfaceId - the interface the caller is requesting.
+
+ Object - a location to store the interface pointer.
+
+ Return Value:
+
+ S_OK or E_NOINTERFACE
+
+--*/
+{
+ //
+ // This class only supports IClassFactory so check for that.
+ //
+
+ if (IsEqualIID(InterfaceId, __uuidof(IClassFactory)))
+ {
+ *Object = QueryIClassFactory();
+ return S_OK;
+ }
+ else
+ {
+ //
+ // See if the base class supports the interface.
+ //
+
+ return CUnknown::QueryInterface(InterfaceId, Object);
+ }
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CClassFactory::CreateInstance(
+ _In_opt_ IUnknown * /* OuterObject */,
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Object
+ )
+/*++
+
+ Routine Description:
+
+ This COM method is the factory routine - it creates instances of the driver
+ callback class and returns the specified interface on them.
+
+ Arguments:
+
+ OuterObject - only used for aggregation, which our driver callback class
+ does not support.
+
+ InterfaceId - the interface ID the caller would like to get from our
+ new object.
+
+ Object - a location to store the referenced interface pointer to the new
+ object.
+
+ Return Value:
+
+ Status.
+
+--*/
+{
+ HRESULT hr;
+
+ PCMyDriver driver;
+
+ *Object = NULL;
+
+ hr = CMyDriver::CreateInstance(&driver);
+
+ if (SUCCEEDED(hr))
+ {
+ hr = driver->QueryInterface(InterfaceId, Object);
+ driver->Release();
+ }
+
+ return hr;
+}
+
+HRESULT
+STDMETHODCALLTYPE
+CClassFactory::LockServer(
+ _In_ BOOL Lock
+ )
+/*++
+
+ Routine Description:
+
+ This COM method can be used to keep the DLL in memory. However since the
+ driver's DllCanUnloadNow function always returns false, this has little
+ effect. Still it tracks the number of lock and unlock operations.
+
+ Arguments:
+
+ Lock - Whether the caller wants to lock or unlock the "server"
+
+ Return Value:
+
+ S_OK
+
+--*/
+{
+ if (Lock)
+ {
+ InterlockedIncrement(&s_LockCount);
+ }
+ else
+ {
+ InterlockedDecrement(&s_LockCount);
+ }
+ return S_OK;
+}
+
diff --git a/tests/projects/wdk/umdf/skeleton/comsup.h b/tests/projects/wdk/umdf/skeleton/comsup.h
new file mode 100644
index 000000000..ba4cd89c3
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/comsup.h
@@ -0,0 +1,215 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved
+
+Module Name:
+
+ ComSup.h
+
+Abstract:
+
+ This module contains classes and functions use for providing COM support
+ code.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#pragma once
+
+//
+// Forward type declarations. They are here rather than in internal.h as
+// you only need them if you choose to use these support classes.
+//
+
+typedef class CUnknown *PCUnknown;
+typedef class CClassFactory *PCClassFactory;
+
+//
+// Base class to implement IUnknown. You can choose to derive your COM
+// classes from this class, or simply implement IUnknown in each of your
+// classes.
+//
+
+class CUnknown : public IUnknown
+{
+
+//
+// Private data members and methods. These are only accessible by the methods
+// of this class.
+//
+private:
+
+ //
+ // The reference count for this object. Initialized to 1 in the
+ // constructor.
+ //
+
+ LONG m_ReferenceCount;
+
+//
+// Protected data members and methods. These are accessible by the subclasses
+// but not by other classes.
+//
+protected:
+
+ //
+ // The constructor and destructor are protected to ensure that only the
+ // subclasses of CUnknown can create and destroy instances.
+ //
+
+ CUnknown(
+ VOID
+ );
+
+ //
+ // The destructor MUST be virtual. Since any instance of a CUnknown
+ // derived class should only be deleted from within CUnknown::Release,
+ // the destructor MUST be virtual or only CUnknown::~CUnknown will get
+ // invoked on deletion.
+ //
+ // If you see that your CMyDevice specific destructor is never being
+ // called, make sure you haven't deleted the virtual destructor here.
+ //
+
+ virtual
+ ~CUnknown(
+ VOID
+ )
+ {
+ // Do nothing
+ }
+
+//
+// Public Methods. These are accessible by any class.
+//
+public:
+
+ IUnknown *
+ QueryIUnknown(
+ VOID
+ );
+
+//
+// COM Methods.
+//
+public:
+
+ //
+ // IUnknown methods
+ //
+
+ virtual
+ ULONG
+ STDMETHODCALLTYPE
+ AddRef(
+ VOID
+ );
+
+ virtual
+ ULONG
+ STDMETHODCALLTYPE
+ Release(
+ VOID
+ );
+
+ virtual
+ HRESULT
+ STDMETHODCALLTYPE
+ QueryInterface(
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Object
+ );
+};
+
+//
+// Class factory support class. Create an instance of this from your
+// DllGetClassObject method and modify the implementation to create
+// an instance of your driver event handler class.
+//
+
+class CClassFactory : public CUnknown, public IClassFactory
+{
+//
+// Private data members and methods. These are only accessible by the methods
+// of this class.
+//
+private:
+
+ //
+ // The lock count. This is shared across all instances of IClassFactory
+ // and can be queried through the public IsLocked method.
+ //
+
+ static LONG s_LockCount;
+
+//
+// Public Methods. These are accessible by any class.
+//
+public:
+
+ IClassFactory *
+ QueryIClassFactory(
+ VOID
+ );
+
+//
+// COM Methods.
+//
+public:
+
+ //
+ // IUnknown methods
+ //
+
+ virtual
+ ULONG
+ STDMETHODCALLTYPE
+ AddRef(
+ VOID
+ )
+ {
+ return __super::AddRef();
+ }
+
+ _At_(this, __drv_freesMem(object))
+ virtual
+ ULONG
+ STDMETHODCALLTYPE
+ Release(
+ VOID
+ )
+ {
+ return __super::Release();
+ }
+
+ virtual
+ HRESULT
+ STDMETHODCALLTYPE
+ QueryInterface(
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Object
+ );
+
+ //
+ // IClassFactory methods.
+ //
+
+ virtual
+ HRESULT
+ STDMETHODCALLTYPE
+ CreateInstance(
+ _In_opt_ IUnknown *OuterObject,
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Object
+ );
+
+ virtual
+ HRESULT
+ STDMETHODCALLTYPE
+ LockServer(
+ _In_ BOOL Lock
+ );
+};
diff --git a/tests/projects/wdk/umdf/skeleton/device.cpp b/tests/projects/wdk/umdf/skeleton/device.cpp
new file mode 100644
index 000000000..2efcd36f0
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/device.cpp
@@ -0,0 +1,238 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved.
+
+Module Name:
+
+ Device.cpp
+
+Abstract:
+
+ This module contains the implementation of the UMDF Skeleton sample driver's
+ device callback object.
+
+ The skeleton sample device does very little. It does not implement either
+ of the PNP interfaces so once the device is setup, it won't ever get any
+ callbacks until the device is removed.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#include "internal.h"
+#include "device.tmh"
+
+HRESULT
+CMyDevice::CreateInstance(
+ _In_ IWDFDriver *FxDriver,
+ _In_ IWDFDeviceInitialize * FxDeviceInit,
+ _Out_ PCMyDevice *Device
+ )
+/*++
+
+ Routine Description:
+
+ This method creates and initializs an instance of the skeleton driver's
+ device callback object.
+
+ Arguments:
+
+ FxDeviceInit - the settings for the device.
+
+ Device - a location to store the referenced pointer to the device object.
+
+ Return Value:
+
+ Status
+
+--*/
+{
+ PCMyDevice device;
+ HRESULT hr;
+
+ //
+ // Allocate a new instance of the device class.
+ //
+
+ device = new CMyDevice();
+
+ if (NULL == device)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ //
+ // Initialize the instance.
+ //
+
+ hr = device->Initialize(FxDriver, FxDeviceInit);
+
+ if (SUCCEEDED(hr))
+ {
+ *Device = device;
+ }
+ else
+ {
+ device->Release();
+ }
+
+ return hr;
+}
+
+HRESULT
+CMyDevice::Initialize(
+ _In_ IWDFDriver * FxDriver,
+ _In_ IWDFDeviceInitialize * FxDeviceInit
+ )
+/*++
+
+ Routine Description:
+
+ This method initializes the device callback object and creates the
+ partner device object.
+
+ The method should perform any device-specific configuration that:
+ * could fail (these can't be done in the constructor)
+ * must be done before the partner object is created -or-
+ * can be done after the partner object is created and which aren't
+ influenced by any device-level parameters the parent (the driver
+ in this case) might set.
+
+ Arguments:
+
+ FxDeviceInit - the settings for this device.
+
+ Return Value:
+
+ status.
+
+--*/
+{
+ IWDFDevice *fxDevice;
+ HRESULT hr;
+
+ //
+ // Configure things like the locking model before we go to create our
+ // partner device.
+ //
+
+ //
+ // Set no locking unless you need an automatic callbacks synchronization
+ //
+
+ FxDeviceInit->SetLockingConstraint(None);
+
+ //
+ // TODO: If you're writing a filter driver then indicate that here.
+ //
+ // FxDeviceInit->SetFilter();
+ //
+
+ //
+ // TODO: Any per-device initialization which must be done before
+ // creating the partner object.
+ //
+
+ //
+ // Create a new FX device object and assign the new callback object to
+ // handle any device level events that occur.
+ //
+
+ //
+ // QueryIUnknown references the IUnknown interface that it returns
+ // (which is the same as referencing the device). We pass that to
+ // CreateDevice, which takes its own reference if everything works.
+ //
+
+ {
+ IUnknown *unknown = this->QueryIUnknown();
+
+ hr = FxDriver->CreateDevice(FxDeviceInit, unknown, &fxDevice);
+
+ unknown->Release();
+ }
+
+ //
+ // If that succeeded then set our FxDevice member variable.
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ m_FxDevice = fxDevice;
+
+ //
+ // Drop the reference we got from CreateDevice. Since this object
+ // is partnered with the framework object they have the same
+ // lifespan - there is no need for an additional reference.
+ //
+
+ fxDevice->Release();
+ }
+
+ return hr;
+}
+
+HRESULT
+CMyDevice::Configure(
+ VOID
+ )
+/*++
+
+ Routine Description:
+
+ This method is called after the device callback object has been initialized
+ and returned to the driver. It would setup the device's queues and their
+ corresponding callback objects.
+
+ Arguments:
+
+ FxDevice - the framework device object for which we're handling events.
+
+ Return Value:
+
+ status
+
+--*/
+{
+ //
+ // TODO: Setup your device queues and I/O forwarding.
+ //
+
+ return S_OK;
+}
+
+HRESULT
+CMyDevice::QueryInterface(
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Object
+ )
+/*++
+
+ Routine Description:
+
+ This method is called to get a pointer to one of the object's callback
+ interfaces.
+
+ Since the skeleton driver doesn't support any of the device events, this
+ method simply calls the base class's BaseQueryInterface.
+
+ If the skeleton is extended to include device event interfaces then this
+ method must be changed to check the IID and return pointers to them as
+ appropriate.
+
+ Arguments:
+
+ InterfaceId - the interface being requested
+
+ Object - a location to store the interface pointer if successful
+
+ Return Value:
+
+ S_OK or E_NOINTERFACE
+
+--*/
+{
+ return CUnknown::QueryInterface(InterfaceId, Object);
+}
diff --git a/tests/projects/wdk/umdf/skeleton/device.h b/tests/projects/wdk/umdf/skeleton/device.h
new file mode 100644
index 000000000..26dd0e329
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/device.h
@@ -0,0 +1,115 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved
+
+Module Name:
+
+ Device.h
+
+Abstract:
+
+ This module contains the type definitions for the UMDF Skeleton sample
+ driver's device callback class.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#pragma once
+
+//
+// Class for the iotrace driver.
+//
+
+class CMyDevice : public CUnknown
+{
+
+//
+// Private data members.
+//
+private:
+
+ IWDFDevice *m_FxDevice;
+
+//
+// Private methods.
+//
+
+private:
+
+ CMyDevice(
+ VOID
+ )
+ {
+ m_FxDevice = NULL;
+ }
+
+ HRESULT
+ Initialize(
+ _In_ IWDFDriver *FxDriver,
+ _In_ IWDFDeviceInitialize *FxDeviceInit
+ );
+
+//
+// Public methods
+//
+public:
+
+ //
+ // The factory method used to create an instance of this driver.
+ //
+
+ static
+ HRESULT
+ CreateInstance(
+ _In_ IWDFDriver *FxDriver,
+ _In_ IWDFDeviceInitialize *FxDeviceInit,
+ _Out_ PCMyDevice *Device
+ );
+
+ HRESULT
+ Configure(
+ VOID
+ );
+
+//
+// COM methods
+//
+public:
+
+ //
+ // IUnknown methods.
+ //
+
+ virtual
+ ULONG
+ STDMETHODCALLTYPE
+ AddRef(
+ VOID
+ )
+ {
+ return __super::AddRef();
+ }
+
+ _At_(this, __drv_freesMem(object))
+ virtual
+ ULONG
+ STDMETHODCALLTYPE
+ Release(
+ VOID
+ )
+ {
+ return __super::Release();
+ }
+
+ virtual
+ HRESULT
+ STDMETHODCALLTYPE
+ QueryInterface(
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Object
+ );
+
+};
diff --git a/tests/projects/wdk/umdf/skeleton/dllsup.cpp b/tests/projects/wdk/umdf/skeleton/dllsup.cpp
new file mode 100644
index 000000000..e540452d9
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/dllsup.cpp
@@ -0,0 +1,177 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved.
+
+Module Name:
+
+ dllsup.cpp
+
+Abstract:
+
+ This module contains the implementation of the UMDF Skeleton Sample
+ Driver's entry point and its exported functions for providing COM support.
+
+ This module can be copied without modification to a new UMDF driver. It
+ depends on some of the code in comsup.cpp & comsup.h to handle DLL
+ registration and creating the first class factory.
+
+ This module is dependent on the following defines:
+
+ MYDRIVER_TRACING_ID - A wide string passed to WPP when initializing
+ tracing. For example the skeleton uses
+ L"Microsoft\\UMDF\\Skeleton"
+
+ MYDRIVER_CLASS_ID - A GUID encoded in struct format used to
+ initialize the driver's ClassID.
+
+ These are defined in internal.h for the sample. If you choose
+ to use a different primary include file, you should ensure they are
+ defined there as well.
+
+Environment:
+
+ WDF User-Mode Driver Framework (WDF:UMDF)
+
+--*/
+
+#include "internal.h"
+#include "dllsup.tmh"
+
+const GUID CLSID_MyDriverCoClass = MYDRIVER_CLASS_ID;
+
+BOOL
+WINAPI
+DllMain(
+ HINSTANCE ModuleHandle,
+ DWORD Reason,
+ PVOID /* Reserved */
+ )
+/*++
+
+ Routine Description:
+
+ This is the entry point and exit point for the I/O trace driver. This
+ does very little as the I/O trace driver has minimal global data.
+
+ This method initializes tracing.
+
+ Arguments:
+
+ ModuleHandle - the DLL handle for this module.
+
+ Reason - the reason this entry point was called.
+
+ Reserved - unused
+
+ Return Value:
+
+ TRUE
+
+--*/
+{
+
+ UNREFERENCED_PARAMETER( ModuleHandle );
+
+ if (DLL_PROCESS_ATTACH == Reason)
+ {
+ //
+ // Initialize tracing.
+ //
+
+ WPP_INIT_TRACING(MYDRIVER_TRACING_ID);
+
+ }
+ else if (DLL_PROCESS_DETACH == Reason)
+ {
+ //
+ // Cleanup tracing.
+ //
+
+ WPP_CLEANUP();
+ }
+
+ return TRUE;
+}
+
+HRESULT
+STDAPICALLTYPE
+DllGetClassObject(
+ _In_ REFCLSID ClassId,
+ _In_ REFIID InterfaceId,
+ _Outptr_ LPVOID *Interface
+ )
+/*++
+
+ Routine Description:
+
+ This routine is called by COM in order to instantiate the
+ driver callback object and do an initial query interface on it.
+
+ This method only creates an instance of the driver's class factory, as this
+ is the minimum required to support UMDF.
+
+ Arguments:
+
+ ClassId - the CLSID of the object being "gotten"
+
+ InterfaceId - the interface the caller wants from that object.
+
+ Interface - a location to store the referenced interface pointer
+
+ Return Value:
+
+ S_OK if the function succeeds or error indicating the cause of the
+ failure.
+
+--*/
+{
+ PCClassFactory factory;
+
+ HRESULT hr = S_OK;
+
+ *Interface = NULL;
+
+ //
+ // If the CLSID doesn't match that of our "coclass" (defined in the IDL
+ // file) then we can't create the object the caller wants. This may
+ // indicate that the COM registration is incorrect, and another CLSID
+ // is referencing this drvier.
+ //
+
+ if (IsEqualCLSID(ClassId, CLSID_MyDriverCoClass) == false)
+ {
+ Trace(
+ TRACE_LEVEL_ERROR,
+ L"ERROR: Called to create instance of unrecognized class (%!GUID!)",
+ &ClassId
+ );
+
+ return CLASS_E_CLASSNOTAVAILABLE;
+ }
+
+ //
+ // Create an instance of the class factory for the caller.
+ //
+
+ factory = new CClassFactory();
+
+ if (NULL == factory)
+ {
+ hr = E_OUTOFMEMORY;
+ }
+
+ //
+ // Query the object we created for the interface the caller wants. After
+ // that we release the object. This will drive the reference count to
+ // 1 (if the QI succeeded an referenced the object) or 0 (if the QI failed).
+ // In the later case the object is automatically deleted.
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = factory->QueryInterface(InterfaceId, Interface);
+ factory->Release();
+ }
+
+ return hr;
+}
diff --git a/tests/projects/wdk/umdf/skeleton/driver.cpp b/tests/projects/wdk/umdf/skeleton/driver.cpp
new file mode 100644
index 000000000..d91b4b0b5
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/driver.cpp
@@ -0,0 +1,220 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved.
+
+Module Name:
+
+ Driver.cpp
+
+Abstract:
+
+ This module contains the implementation of the UMDF Skeleton Sample's
+ core driver callback object.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#include "internal.h"
+#include "driver.tmh"
+
+HRESULT
+CMyDriver::CreateInstance(
+ _Out_ PCMyDriver *Driver
+ )
+/*++
+
+ Routine Description:
+
+ This static method is invoked in order to create and initialize a new
+ instance of the driver class. The caller should arrange for the object
+ to be released when it is no longer in use.
+
+ Arguments:
+
+ Driver - a location to store a referenced pointer to the new instance
+
+ Return Value:
+
+ S_OK if successful, or error otherwise.
+
+--*/
+{
+ PCMyDriver driver;
+ HRESULT hr;
+
+ //
+ // Allocate the callback object.
+ //
+
+ driver = new CMyDriver();
+
+ if (NULL == driver)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ //
+ // Initialize the callback object.
+ //
+
+ hr = driver->Initialize();
+
+ if (SUCCEEDED(hr))
+ {
+ //
+ // Store a pointer to the new, initialized object in the output
+ // parameter.
+ //
+
+ *Driver = driver;
+ }
+ else
+ {
+
+ //
+ // Release the reference on the driver object to get it to delete
+ // itself.
+ //
+
+ driver->Release();
+ }
+
+ return hr;
+}
+
+HRESULT
+CMyDriver::Initialize(
+ VOID
+ )
+/*++
+
+ Routine Description:
+
+ This method is called to initialize a newly created driver callback object
+ before it is returned to the creator. Unlike the constructor, the
+ Initialize method contains operations which could potentially fail.
+
+ Arguments:
+
+ None
+
+ Return Value:
+
+ None
+
+--*/
+{
+ return S_OK;
+}
+
+HRESULT
+CMyDriver::QueryInterface(
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Interface
+ )
+/*++
+
+ Routine Description:
+
+ This method returns a pointer to the requested interface on the callback
+ object..
+
+ Arguments:
+
+ InterfaceId - the IID of the interface to query/reference
+
+ Interface - a location to store the interface pointer.
+
+ Return Value:
+
+ S_OK if the interface is supported.
+ E_NOINTERFACE if it is not supported.
+
+--*/
+{
+ if (IsEqualIID(InterfaceId, __uuidof(IDriverEntry)))
+ {
+ *Interface = QueryIDriverEntry();
+ return S_OK;
+ }
+ else
+ {
+ return CUnknown::QueryInterface(InterfaceId, Interface);
+ }
+}
+
+HRESULT
+CMyDriver::OnDeviceAdd(
+ _In_ IWDFDriver *FxWdfDriver,
+ _In_ IWDFDeviceInitialize *FxDeviceInit
+ )
+/*++
+
+ Routine Description:
+
+ The FX invokes this method when it wants to install our driver on a device
+ stack. This method creates a device callback object, then calls the Fx
+ to create an Fx device object and associate the new callback object with
+ it.
+
+ Arguments:
+
+ FxWdfDriver - the Fx driver object.
+
+ FxDeviceInit - the initialization information for the device.
+
+ Return Value:
+
+ status
+
+--*/
+{
+ HRESULT hr;
+
+ PCMyDevice device = NULL;
+
+ //
+ // TODO: Do any per-device initialization (reading settings from the
+ // registry for example) that's necessary before creating your
+ // device callback object here. Otherwise you can leave such
+ // initialization to the initialization of the device event
+ // handler.
+ //
+
+ //
+ // Create a new instance of our device callback object
+ //
+
+ hr = CMyDevice::CreateInstance(FxWdfDriver, FxDeviceInit, &device);
+
+ //
+ // TODO: Change any per-device settings that the object exposes before
+ // calling Configure to let it complete its initialization.
+ //
+
+ //
+ // If that succeeded then call the device's construct method. This
+ // allows the device to create any queues or other structures that it
+ // needs now that the corresponding fx device object has been created.
+ //
+
+ if (SUCCEEDED(hr))
+ {
+ hr = device->Configure();
+ }
+
+ //
+ // Release the reference on the device callback object now that it's been
+ // associated with an fx device object.
+ //
+
+ if (NULL != device)
+ {
+ device->Release();
+ }
+
+ return hr;
+}
diff --git a/tests/projects/wdk/umdf/skeleton/driver.h b/tests/projects/wdk/umdf/skeleton/driver.h
new file mode 100644
index 000000000..e764f517d
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/driver.h
@@ -0,0 +1,149 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved
+
+Module Name:
+
+ Driver.h
+
+Abstract:
+
+ This module contains the type definitions for the UMDF Skeleton sample's
+ driver callback class.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#pragma once
+
+//
+// This class handles driver events for the skeleton sample. In particular
+// it supports the OnDeviceAdd event, which occurs when the driver is called
+// to setup per-device handlers for a new device stack.
+//
+
+class CMyDriver : public CUnknown, public IDriverEntry
+{
+//
+// Private data members.
+//
+private:
+
+//
+// Private methods.
+//
+private:
+
+ //
+ // Returns a refernced pointer to the IDriverEntry interface.
+ //
+
+ IDriverEntry *
+ QueryIDriverEntry(
+ VOID
+ )
+ {
+ AddRef();
+ return static_cast<IDriverEntry*>(this);
+ }
+
+ HRESULT
+ Initialize(
+ VOID
+ );
+
+//
+// Public methods
+//
+public:
+
+ //
+ // The factory method used to create an instance of this driver.
+ //
+
+ static
+ HRESULT
+ CreateInstance(
+ _Out_ PCMyDriver *Driver
+ );
+
+//
+// COM methods
+//
+public:
+
+ //
+ // IDriverEntry methods
+ //
+
+ virtual
+ HRESULT
+ STDMETHODCALLTYPE
+ OnInitialize(
+ _In_ IWDFDriver *FxWdfDriver
+ )
+ {
+ UNREFERENCED_PARAMETER( FxWdfDriver );
+
+ return S_OK;
+ }
+
+ virtual
+ HRESULT
+ STDMETHODCALLTYPE
+ OnDeviceAdd(
+ _In_ IWDFDriver *FxWdfDriver,
+ _In_ IWDFDeviceInitialize *FxDeviceInit
+ );
+
+ virtual
+ VOID
+ STDMETHODCALLTYPE
+ OnDeinitialize(
+ _In_ IWDFDriver *FxWdfDriver
+ )
+ {
+ UNREFERENCED_PARAMETER( FxWdfDriver );
+
+ return;
+ }
+
+ //
+ // IUnknown methods.
+ //
+ // We have to implement basic ones here that redirect to the
+ // base class becuase of the multiple inheritance.
+ //
+
+ virtual
+ ULONG
+ STDMETHODCALLTYPE
+ AddRef(
+ VOID
+ )
+ {
+ return __super::AddRef();
+ }
+
+ _At_(this, __drv_freesMem(object))
+ virtual
+ ULONG
+ STDMETHODCALLTYPE
+ Release(
+ VOID
+ )
+ {
+ return __super::Release();
+ }
+
+ virtual
+ HRESULT
+ STDMETHODCALLTYPE
+ QueryInterface(
+ _In_ REFIID InterfaceId,
+ _Out_ PVOID *Object
+ );
+};
diff --git a/tests/projects/wdk/umdf/skeleton/exports.def b/tests/projects/wdk/umdf/skeleton/exports.def
new file mode 100644
index 000000000..7d46558b7
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/exports.def
@@ -0,0 +1,10 @@
+; Skeleton.def : Declares the module parameters.
+
+;
+; TODO: Change the library name here to match your binary name.
+;
+
+LIBRARY "UMDFSkeleton.DLL"
+
+EXPORTS
+ DllGetClassObject PRIVATE
diff --git a/tests/projects/wdk/umdf/skeleton/internal.h b/tests/projects/wdk/umdf/skeleton/internal.h
new file mode 100644
index 000000000..f338a9b6c
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/internal.h
@@ -0,0 +1,90 @@
+/*++
+
+Copyright (C) Microsoft Corporation, All Rights Reserved
+
+Module Name:
+
+ Internal.h
+
+Abstract:
+
+ This module contains the local type definitions for the UMDF Skeleton
+ driver sample.
+
+Environment:
+
+ Windows User-Mode Driver Framework (WUDF)
+
+--*/
+
+#pragma once
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+//
+// Include the WUDF DDI
+//
+
+#include "wudfddi.h"
+
+//
+// Use specstrings for in/out annotation of function parameters.
+//
+
+#include "specstrings.h"
+
+//
+// Forward definitions of classes in the other header files.
+//
+
+typedef class CMyDriver *PCMyDriver;
+typedef class CMyDevice *PCMyDevice;
+
+//
+// Define the tracing flags.
+//
+// TODO: Choose a different trace control GUID
+//
+
+#define WPP_CONTROL_GUIDS \
+ WPP_DEFINE_CONTROL_GUID( \
+ MyDriverTraceControl, (e7541cdd,30e8,4b50,aeb0,51927330ae64), \
+ \
+ WPP_DEFINE_BIT(MYDRIVER_ALL_INFO) \
+ )
+
+#define WPP_FLAG_LEVEL_LOGGER(flag, level) \
+ WPP_LEVEL_LOGGER(flag)
+
+#define WPP_FLAG_LEVEL_ENABLED(flag, level) \
+ (WPP_LEVEL_ENABLED(flag) && \
+ WPP_CONTROL(WPP_BIT_ ## flag).Level >= level)
+
+//
+// This comment block is scanned by the trace preprocessor to define our
+// Trace function.
+//
+// begin_wpp config
+// FUNC Trace{FLAG=MYDRIVER_ALL_INFO}(LEVEL, MSG, ...);
+// end_wpp
+//
+
+//
+// Driver specific #defines
+//
+// TODO: Change these values to be appropriate for your driver.
+//
+
+#define MYDRIVER_TRACING_ID L"Microsoft\\UMDF\\Skeleton"
+#define MYDRIVER_CLASS_ID { 0xd4112073, 0xd09b, 0x458f, { 0xa5, 0xaa, 0x35, 0xef, 0x21, 0xee, 0xf5, 0xde } }
+
+
+//
+// Include the type specific headers.
+//
+
+#include "comsup.h"
+#include "driver.h"
+#include "device.h"
diff --git a/tests/projects/wdk/umdf/skeleton/xmake.lua b/tests/projects/wdk/umdf/skeleton/xmake.lua
new file mode 100644
index 000000000..6bfa00aca
--- /dev/null
+++ b/tests/projects/wdk/umdf/skeleton/xmake.lua
@@ -0,0 +1,29 @@
+
+-- add modes: debug and release
+add_rules("mode.debug", "mode.release")
+
+-- enable unicode
+add_defines("_UNICODE", "UNICODE")
+
+-- add target
+target("skeleton")
+
+ -- add rules
+ add_rules("wdk.umdf.driver")
+
+ -- add flags fro tracewpp
+ add_values("wdk.tracewpp.flags", "-scan:internal.h")
+
+ -- add files
+ add_files("*.cpp", {rule = "wdk.tracewpp"})
+ add_files("*.rc", "*.inx")
+
+ -- set umdf sdk version
+ set_values("wdk.umdf.sdkver", "1.9")
+
+ -- add exports
+ add_shflags("/DEF:exports.def", {force = true})
+
+ -- set entry
+ add_shflags("/ENTRY:_DllMainCRTStartup", {force = true})
+
diff --git a/xmake/rules/wdk/env/xmake.lua b/xmake/rules/wdk/env/xmake.lua
index 53d2e942e..c0b98cff0 100644
--- a/xmake/rules/wdk/env/xmake.lua
+++ b/xmake/rules/wdk/env/xmake.lua
@@ -27,9 +27,30 @@ rule("wdk.env")
-- on load
on_load(function (target)
+
+ -- imports
import("detect.sdks.find_wdk")
+
+ -- load wdk environment
if not target:data("wdk") then
- target:data_set("wdk", assert(find_wdk(nil, {verbose = true}), "WDK not found!"))
+
+ -- find wdk
+ local wdk = assert(find_wdk(nil, {verbose = true}), "WDK not found!")
+
+ -- update the umdf sdk version from the xmake.lua
+ local umdfver = target:values("wdk.umdf.sdkver")
+ if umdfver then
+ wdk.umdfver = umdfver
+ end
+
+ -- update the kmdf sdk version from the xmake.lua
+ local kmdfver = target:values("wdk.kmdf.sdkver")
+ if kmdfver then
+ wdk.kmdfver = kmdfver
+ end
+
+ -- save wdk
+ target:data_set("wdk", wdk)
end
end)
diff --git a/xmake/rules/wdk/inf/xmake.lua b/xmake/rules/wdk/inf/xmake.lua
index 3cec2660b..3052ec275 100644
--- a/xmake/rules/wdk/inf/xmake.lua
+++ b/xmake/rules/wdk/inf/xmake.lua
@@ -61,10 +61,29 @@ rule("wdk.inf")
-- add clean files
target:data_add("wdk.cleanfiles", targetfile)
+ -- init args
+ local args = {"-d", "*", "-a", is_arch("x64") and "arm64" or "x86", "-v", "*"}
+ local flags = target:values("wdk.inf.flags", sourcefile)
+ if flags then
+ table.join2(args, flags)
+ end
+ local wdk = target:data("wdk")
+ if wdk then
+ if wdk.kmdfver and (target:rule("wdk.kmdf.driver") or target:rule("wdk.kmdf.binary")) then
+ table.insert(args, "-k")
+ table.insert(args, wdk.kmdfver)
+ elseif wdk.umdfver then
+ table.insert(args, "-u")
+ table.insert(args, wdk.umdfver .. ".0")
+ end
+ end
+ table.insert(args, "-f")
+ table.insert(args, targetfile)
+
-- need build this object?
local dependfile = target:dependfile(targetfile)
local dependinfo = option.get("rebuild") and {} or (depend.load(dependfile) or {})
- if not depend.is_changed(dependinfo, {lastmtime = os.mtime(targetfile)}) then
+ if not depend.is_changed(dependinfo, {lastmtime = os.mtime(targetfile), values = args}) then
return
end
@@ -80,10 +99,11 @@ rule("wdk.inf")
-- update the timestamp
os.cp(sourcefile, targetfile)
- os.vrunv(stampinf, {"-d", "*", "-a", is_arch("x64") and "arm64" or "x86", "-v", "*", "-f", targetfile}, {wildcards = false})
+ os.vrunv(stampinf, args, {wildcards = false})
-- update files and values to the dependent file
dependinfo.files = {sourcefile}
+ dependinfo.values = args
depend.save(dependinfo, dependfile)
end)
diff --git a/xmake/rules/wdk/load.lua b/xmake/rules/wdk/load.lua
index 7ea5d1aba..b8cbcfc01 100644
--- a/xmake/rules/wdk/load.lua
+++ b/xmake/rules/wdk/load.lua
@@ -52,8 +52,24 @@ function umdf_driver(target)
target:add("linkdirs", path.join(wdk.libdir, "wdf", "umdf", arch, wdk.umdfver))
-- add links
- target:add("links", "WdfDriverStubUm", "ntdll", "OneCoreUAP", "mincore", "ucrt")
- target:add("ldflags", "-NODEFAULTLIB:kernel32.lib", "-NODEFAULTLIB:user32.lib", "-NODEFAULTLIB:libucrt.lib", {force = true})
+ target:add("links", "ntdll", "OneCoreUAP", "mincore", "ucrt")
+ target:add("shflags", "-NODEFAULTLIB:kernel32.lib", "-NODEFAULTLIB:user32.lib", "-NODEFAULTLIB:libucrt.lib", {force = true})
+
+ -- set subsystem: windows, TODO 10.00
+ target:add("shflags", "-subsystem:windows,10.00", {force = true})
+
+ -- set default driver entry if does not exist
+ local entry = false
+ for _, ldflag in ipairs(target:get("shflags")) do
+ ldflag = ldflag:lower()
+ if ldflag:find("[/%-]entry:") then
+ entry = true
+ break
+ end
+ end
+ if not entry then
+ target:add("links", "WdfDriverStubUm")
+ end
end
-- load for umdf binary