[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[win-pv-devel] [PATCH] Move interface subscription code into co-installer



Interface subscription is better handled at package installation time and
therefore the co-installer is the right place for it to live.

Signed-off-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
---
 src/coinst/coinst.c                 | 190 ++++++++++++++++++++++++++++++++++++
 src/xenvbd/fdo.c                    | 145 ++++++---------------------
 vs2012/coinst/xenvbd_coinst.vcxproj |   2 +-
 vs2013/coinst/xenvbd_coinst.vcxproj |   4 +-
 4 files changed, 224 insertions(+), 117 deletions(-)

diff --git a/src/coinst/coinst.c b/src/coinst/coinst.c
index bb00468..7233b9b 100644
--- a/src/coinst/coinst.c
+++ b/src/coinst/coinst.c
@@ -35,6 +35,13 @@
 #include <stdlib.h>
 #include <strsafe.h>
 
+#include <debug_interface.h>
+#include <suspend_interface.h>
+#include <evtchn_interface.h>
+#include <store_interface.h>
+#include <gnttab_interface.h>
+#include <emulated_interface.h>
+
 #include <version.h>
 
 __user_code;
@@ -646,6 +653,176 @@ fail1:
     return FALSE;
 }
 
+static HKEY
+OpenInterfacesKey(
+    IN  PTCHAR  ProviderName
+    )
+{
+    HRESULT     Result;
+    TCHAR       KeyName[MAX_PATH];
+    HKEY        Key;
+    HRESULT     Error;
+
+    Result = StringCbPrintf(KeyName,
+                            MAX_PATH,
+                            "%s\\%s\\Interfaces",
+                            SERVICES_KEY,
+                            ProviderName);
+    if (!SUCCEEDED(Result)) {
+        SetLastError(ERROR_BUFFER_OVERFLOW);
+        goto fail1;
+    }
+
+    Error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+                         KeyName,
+                         0,
+                         KEY_ALL_ACCESS,
+                         &Key);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    return Key;
+
+fail2:
+    Log("fail2");
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return NULL;
+}
+
+static BOOLEAN
+SubscribeInterface(
+    IN  PTCHAR  ProviderName,
+    IN  PTCHAR  SubscriberName,
+    IN  PTCHAR  InterfaceName,
+    IN  DWORD   InterfaceVersion
+    )
+{
+    HKEY        Key;
+    HKEY        InterfacesKey;
+    HRESULT     Error;
+
+    InterfacesKey = OpenInterfacesKey(ProviderName);
+    if (InterfacesKey == NULL)
+        goto fail1;
+
+    Error = RegCreateKeyEx(InterfacesKey,
+                           SubscriberName,
+                           0,
+                           NULL,
+                           REG_OPTION_NON_VOLATILE,
+                           KEY_ALL_ACCESS,
+                           NULL,
+                           &Key,
+                           NULL);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    Error = RegSetValueEx(Key,
+                          InterfaceName,
+                          0,
+                          REG_DWORD,
+                          (const BYTE *)&InterfaceVersion,
+                          sizeof(DWORD));
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail3;
+    }
+
+    Log("%s: %s_%s_INTERFACE_VERSION %u",
+        SubscriberName,
+        ProviderName,
+        InterfaceName,
+        InterfaceVersion);
+
+    RegCloseKey(Key);
+    RegCloseKey(InterfacesKey);
+
+    return TRUE;
+
+fail3:
+    RegCloseKey(Key);
+
+fail2:
+    RegCloseKey(InterfacesKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
+#define SUBSCRIBE_INTERFACE(_ProviderName, _SubscriberName, _InterfaceName)    
                    \
+    do {                                                                       
                    \
+        (VOID) SubscribeInterface(#_ProviderName,                              
                    \
+                                  #_SubscriberName,                            
                    \
+                                  #_InterfaceName,                             
                    \
+                                  _ProviderName ## _ ## _InterfaceName ## 
_INTERFACE_VERSION_MAX); \
+    } while (FALSE);
+
+static BOOLEAN
+UnsubscribeInterfaces(
+    IN  PTCHAR  ProviderName,
+    IN  PTCHAR  SubscriberName
+    )
+{
+    HKEY        InterfacesKey;
+    HRESULT     Error;
+
+    Log("%s: %s", SubscriberName, ProviderName);
+
+    InterfacesKey = OpenInterfacesKey(ProviderName);
+    if (InterfacesKey == NULL) {
+        goto fail1;
+    }
+
+    Error = RegDeleteTree(InterfacesKey,
+                          SubscriberName);
+    if (Error != ERROR_SUCCESS) {
+        SetLastError(Error);
+        goto fail2;
+    }
+
+    RegCloseKey(InterfacesKey);
+
+    return TRUE;
+
+fail2:
+    RegCloseKey(InterfacesKey);
+
+fail1:
+    Error = GetLastError();
+
+    {
+        PTCHAR  Message;
+        Message = __GetErrorMessage(Error);
+        Log("fail1 (%s)", Message);
+        LocalFree(Message);
+    }
+
+    return FALSE;
+}
+
 static FORCEINLINE HRESULT
 __DifInstallPreProcess(
     IN  HDEVINFO                    DeviceInfoSet,
@@ -675,9 +852,19 @@ __DifInstallPostProcess(
 
     Log("====>");
 
+    SUBSCRIBE_INTERFACE(XENBUS, XENVBD, STORE);
+    SUBSCRIBE_INTERFACE(XENBUS, XENVBD, EVTCHN);
+    SUBSCRIBE_INTERFACE(XENBUS, XENVBD, GNTTAB);
+    SUBSCRIBE_INTERFACE(XENBUS, XENVBD, SUSPEND);
+    SUBSCRIBE_INTERFACE(XENBUS, XENVBD, DEBUG);
+
+    SUBSCRIBE_INTERFACE(XENFILT, XENVBD, EMULATED);
+
     (VOID) OverrideGroupPolicyOptions();
     (VOID) IncreaseDiskTimeOut();
+
     (VOID) InstallUnplugService("DISKS", "XENVBD");
+
     (VOID) RequestReboot(DeviceInfoSet, DeviceInfoData);
 
     Log("<====");
@@ -756,6 +943,9 @@ __DifRemovePreProcess(
 
     (VOID) RemoveUnplugService("DISKS", "XENVBD");
 
+    UnsubscribeInterfaces("XENFILT", "XENVBD");
+    UnsubscribeInterfaces("XENBUS", "XENVBD");
+
     return NO_ERROR; 
 }
 
diff --git a/src/xenvbd/fdo.c b/src/xenvbd/fdo.c
index 2ee91b8..68bf95c 100644
--- a/src/xenvbd/fdo.c
+++ b/src/xenvbd/fdo.c
@@ -261,73 +261,29 @@ FdoUnlinkPdo(
 //=============================================================================
 // QueryInterface
 
-#define SERVICES_KEY        
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services"
-
-__checkReturn
-__drv_maxIRQL(PASSIVE_LEVEL)
-static FORCEINLINE NTSTATUS
-__QueryInterface(
-    __in    PDEVICE_OBJECT  DeviceObject,
-    __in    const WCHAR     *ProviderName,
-    __in    const CHAR      *InterfaceName,
-    __in    const GUID      *Guid,
-    __in    ULONG           Version,
-    __inout PINTERFACE      Interface,
-    __in    ULONG           Size,
-    __in    BOOLEAN         Optional
+static NTSTATUS
+FdoQueryInterface(
+    IN  PXENVBD_FDO     Fdo,
+    IN  const GUID      *Guid,
+    IN  ULONG           Version,
+    OUT PINTERFACE      Interface,
+    IN  ULONG           Size,
+    IN  BOOLEAN         Optional
     )
 {
-    UNICODE_STRING          Unicode;
-    HANDLE                  InterfacesKey;
-    HANDLE                  SubscriberKey;
-    KEVENT                  Event;
-    IO_STATUS_BLOCK         StatusBlock;
-    PIRP                    Irp;
-    PIO_STACK_LOCATION      StackLocation;
-    NTSTATUS                status;
+    KEVENT              Event;
+    IO_STATUS_BLOCK     StatusBlock;
+    PIRP                Irp;
+    PIO_STACK_LOCATION  StackLocation;
+    NTSTATUS            status;
 
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
 
-    Unicode.MaximumLength = (USHORT)((wcslen(SERVICES_KEY) +
-                                      1 +
-                                      wcslen(ProviderName) +
-                                      1 +
-                                      wcslen(L"Interfaces") +
-                                      1) * sizeof (WCHAR));
-
-    Unicode.Buffer = __AllocateNonPagedPoolWithTag(__FUNCTION__,
-                                                   __LINE__,
-                                                   Unicode.MaximumLength,
-                                                   FDO_SIGNATURE);
-
-    status = STATUS_NO_MEMORY;
-    if (Unicode.Buffer == NULL)
-        goto fail1;
-
-    status = RtlStringCbPrintfW(Unicode.Buffer,
-                                Unicode.MaximumLength,
-                                SERVICES_KEY L"\\%ws\\Interfaces",
-                                ProviderName);
-    ASSERT(NT_SUCCESS(status));
-
-    Unicode.Length = (USHORT)(wcslen(Unicode.Buffer) * sizeof (WCHAR));
-
-    status = RegistryOpenKey(NULL, &Unicode, KEY_READ, &InterfacesKey);
-    if (!NT_SUCCESS(status))
-        goto fail2;
-
-    status = RegistryCreateSubKey(InterfacesKey, 
-                                  "XENVBD",
-                                  REG_OPTION_NON_VOLATILE, 
-                                  &SubscriberKey);
-    if (!NT_SUCCESS(status))
-        goto fail3;
-                   
     KeInitializeEvent(&Event, NotificationEvent, FALSE);
     RtlZeroMemory(&StatusBlock, sizeof(IO_STATUS_BLOCK));
 
     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_PNP,
-                                       DeviceObject,
+                                       Fdo->LowerDeviceObject,
                                        NULL,
                                        0,
                                        NULL,
@@ -336,7 +292,7 @@ __QueryInterface(
 
     status = STATUS_UNSUCCESSFUL;
     if (Irp == NULL)
-        goto fail4;
+        goto fail1;
 
     StackLocation = IoGetNextIrpStackLocation(Irp);
     StackLocation->MinorFunction = IRP_MN_QUERY_INTERFACE;
@@ -348,7 +304,7 @@ __QueryInterface(
     
     Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
 
-    status = IoCallDriver(DeviceObject, Irp);
+    status = IoCallDriver(Fdo->LowerDeviceObject, Irp);
     if (status == STATUS_PENDING) {
         (VOID) KeWaitForSingleObject(&Event,
                                      Executive,
@@ -362,67 +318,34 @@ __QueryInterface(
         if (status == STATUS_NOT_SUPPORTED && Optional)
             goto done;
 
-        goto fail5;
+        goto fail2;
     }
 
-    status = RegistryUpdateDwordValue(SubscriberKey,
-                                      (PCHAR)InterfaceName,
-                                      Version);
-    if (!NT_SUCCESS(status))
-        goto fail6;
-
 done:
-    RegistryCloseKey(SubscriberKey);
-
-    RegistryCloseKey(InterfacesKey);
-
-    __FreePoolWithTag(Unicode.Buffer, FDO_SIGNATURE);
-
     return STATUS_SUCCESS;
 
-fail6:
-    Error("fail6\n");
-
-fail5:
-    Error("fail5\n");
-
-fail4:
-    Error("fail4\n");
-
-    RegistryCloseKey(SubscriberKey);
-
-fail3:
-    Error("fail3\n");
-
-    RegistryCloseKey(InterfacesKey);
-
 fail2:
     Error("fail2\n");
 
-    __FreePoolWithTag(Unicode.Buffer, FDO_SIGNATURE);
-
 fail1:
     Error("fail1 (%08x)\n", status);
 
     return status;
 }
 
-#define QUERY_INTERFACE(                                                       
         \
-    _DeviceObject,                                                             
         \
+#define QUERY_INTERFACE(                                                       
     \
+    _Fdo,                                                                      
         \
     _ProviderName,                                                             
         \
     _InterfaceName,                                                            
         \
-    _Version,                                                                  
         \
     _Interface,                                                                
         \
     _Size,                                                                     
         \
     _Optional)                                                                 
         \
-    __QueryInterface((_DeviceObject),                                          
         \
-                     L ## #_ProviderName,                                      
         \
-                     #_InterfaceName,                                          
         \
-                     &GUID_ ## _ProviderName ## _ ## _InterfaceName ## 
_INTERFACE,      \
-                     (_Version),                                               
         \
-                     (_Interface),                                             
         \
-                     (_Size),                                                  
         \
-                     (_Optional))
+    FdoQueryInterface((_Fdo),                                                  
         \
+                      &GUID_ ## _ProviderName ## _ ## _InterfaceName ## 
_INTERFACE,     \
+                      _ProviderName ## _ ## _InterfaceName ## 
_INTERFACE_VERSION_MAX,   \
+                      (_Interface),                                            
         \
+                      (_Size),                                                 
         \
+                      (_Optional))
 
 //=============================================================================
 // Debug
@@ -921,10 +844,9 @@ __FdoQueryInterfaces(
     ASSERT3U(KeGetCurrentIrql(), ==, PASSIVE_LEVEL);
 
     // Get STORE Interface
-    Status = QUERY_INTERFACE(Fdo->LowerDeviceObject,
+    Status = QUERY_INTERFACE(Fdo,
                              XENBUS,
                              STORE,
-                             XENBUS_STORE_INTERFACE_VERSION_MAX,
                              (PINTERFACE)&Fdo->Store,
                              sizeof (Fdo->Store),
                              FALSE);
@@ -932,10 +854,9 @@ __FdoQueryInterfaces(
         goto fail1;
 
     // Get EVTCHN Interface
-    Status = QUERY_INTERFACE(Fdo->LowerDeviceObject,
+    Status = QUERY_INTERFACE(Fdo,
                              XENBUS,
                              EVTCHN,
-                             XENBUS_EVTCHN_INTERFACE_VERSION_MAX,
                              (PINTERFACE)&Fdo->Evtchn,
                              sizeof (Fdo->Evtchn),
                              FALSE);
@@ -943,10 +864,9 @@ __FdoQueryInterfaces(
         goto fail2;
 
     // Get GNTTAB Interface
-    Status = QUERY_INTERFACE(Fdo->LowerDeviceObject,
+    Status = QUERY_INTERFACE(Fdo,
                              XENBUS,
                              GNTTAB,
-                             XENBUS_GNTTAB_INTERFACE_VERSION_MAX,
                              (PINTERFACE)&Fdo->Gnttab,
                              sizeof (Fdo->Gnttab),
                              FALSE);
@@ -954,10 +874,9 @@ __FdoQueryInterfaces(
         goto fail3;
 
     // Get SUSPEND Interface
-    Status = QUERY_INTERFACE(Fdo->LowerDeviceObject,
+    Status = QUERY_INTERFACE(Fdo,
                              XENBUS,
                              SUSPEND,
-                             XENBUS_SUSPEND_INTERFACE_VERSION_MAX,
                              (PINTERFACE)&Fdo->Suspend,
                              sizeof (Fdo->Suspend),
                              FALSE);
@@ -965,10 +884,9 @@ __FdoQueryInterfaces(
         goto fail4;
 
     // Get DEBUG Interface
-    Status = QUERY_INTERFACE(Fdo->LowerDeviceObject,
+    Status = QUERY_INTERFACE(Fdo,
                              XENBUS,
                              DEBUG,
-                             XENBUS_DEBUG_INTERFACE_VERSION_MAX,
                              (PINTERFACE)&Fdo->Debug,
                              sizeof (Fdo->Debug),
                              FALSE);
@@ -976,10 +894,9 @@ __FdoQueryInterfaces(
         goto fail5;
 
     // Get EMULATED Interface (optional)
-    Status = QUERY_INTERFACE(Fdo->LowerDeviceObject,
+    Status = QUERY_INTERFACE(Fdo,
                              XENFILT,
                              EMULATED,
-                             XENFILT_EMULATED_INTERFACE_VERSION_MAX,
                              (PINTERFACE)&Fdo->Emulated,
                              sizeof (Fdo->Emulated),
                              TRUE);
diff --git a/vs2012/coinst/xenvbd_coinst.vcxproj 
b/vs2012/coinst/xenvbd_coinst.vcxproj
index 865baf4..f83edfc 100644
--- a/vs2012/coinst/xenvbd_coinst.vcxproj
+++ b/vs2012/coinst/xenvbd_coinst.vcxproj
@@ -36,7 +36,7 @@
                <ClCompile>
                        
<PreprocessorDefinitions>__MODULE__="XENVBD_COINST";%(PreprocessorDefinitions)</PreprocessorDefinitions>
                        <WarningLevel>EnableAllWarnings</WarningLevel>
-                       
<DisableSpecificWarnings>4548;4711;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+                       
<DisableSpecificWarnings>4127;4548;4711;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
                        
<MultiProcessorCompilation>true</MultiProcessorCompilation>
                        <EnablePREfast>true</EnablePREfast>
                        <RuntimeLibrary 
Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
diff --git a/vs2013/coinst/xenvbd_coinst.vcxproj 
b/vs2013/coinst/xenvbd_coinst.vcxproj
index 817f4ee..7cbabbb 100644
--- a/vs2013/coinst/xenvbd_coinst.vcxproj
+++ b/vs2013/coinst/xenvbd_coinst.vcxproj
@@ -1,4 +1,4 @@
-ï<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" 
xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
   <Import Project="..\configs.props" />
   <PropertyGroup Label="PropertySheets">
@@ -65,7 +65,7 @@
     <ClCompile>
       
<PreprocessorDefinitions>__MODULE__="XENVBD_COINST";%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <WarningLevel>EnableAllWarnings</WarningLevel>
-      
<DisableSpecificWarnings>4548;4711;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+      
<DisableSpecificWarnings>4127;4548;4711;4820;4668;4255;6001;6054;28196;%(DisableSpecificWarnings)</DisableSpecificWarnings>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <EnablePREfast>true</EnablePREfast>
       <RuntimeLibrary 
Condition="'$(UseDebugLibraries)'=='true'">MultiThreadedDebug</RuntimeLibrary>
-- 
2.1.1


_______________________________________________
win-pv-devel mailing list
win-pv-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/win-pv-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.