]> xenbits.xensource.com Git - pvdrivers/win/xenvbd.git/commitdiff
Fix SDV errors, completes SDV and DVL log run
authorOwen Smith <owen.smith@citrix.com>
Mon, 19 May 2014 09:32:16 +0000 (10:32 +0100)
committerOwen Smith <owen.smith@citrix.com>
Mon, 19 May 2014 09:32:16 +0000 (10:32 +0100)
Notes: Date format must be US (MM/DD/YY) for WHQL tests

Signed-off-by: Owen Smith <owen.smith@citrix.com>
15 files changed:
build.py
proj/xenvbd/xenvbd.vcxproj
src/xenvbd/blockring.c
src/xenvbd/debug.h
src/xenvbd/driver.c
src/xenvbd/fdo.h
src/xenvbd/frontend.c
src/xenvbd/pdo-inquiry.c [deleted file]
src/xenvbd/pdo-inquiry.h [deleted file]
src/xenvbd/pdo.c
src/xenvbd/pdo.h
src/xenvbd/pdoinquiry.c [new file with mode: 0644]
src/xenvbd/pdoinquiry.h [new file with mode: 0644]
src/xenvbd/queue.h
src/xenvbd/srbext.h

index fcaacc09c8e76927347794770e4e2b1e6c7b0c7b..ec6222e82505f8d624b1af2e3dba1da9fe8f8c48 100644 (file)
--- a/build.py
+++ b/build.py
@@ -390,7 +390,6 @@ if __name__ == '__main__':
     symstore_add(driver, release, 'x64', debug[sys.argv[1]])
 
     if len(sys.argv) <= 2 or sdv[sys.argv[2]]:
-        run_sdv('xencrsh', driver)
         run_sdv('xenvbd', driver)
 
     archive(driver + '\\source.tgz', manifest().splitlines(), tgz=True)
index 72a5a52d03b893a57ec5fd9b1273f96986f9136e..b32e00799258336e40c4ce9e3195d8708637d508 100644 (file)
@@ -77,7 +77,7 @@
                <ClCompile Include="../../src/xenvbd/fdo.c" />
                <ClCompile Include="../../src/xenvbd/frontend.c" />
                <ClCompile Include="../../src/xenvbd/pdo.c" />
-               <ClCompile Include="../../src/xenvbd/pdo-inquiry.c" />
+               <ClCompile Include="../../src/xenvbd/pdoinquiry.c" />
                <ClCompile Include="../../src/xenvbd/queue.c" />
                <ClCompile Include="../../src/xenvbd/thread.c" />
                <ClCompile Include="../../src/xenvbd/notifier.c" />
index be4c13f48cf004aed443b8adf48bea55b1f767ba..2430874ae3a05ebc93d4a0a8d404ab5642388e4e 100644 (file)
@@ -339,7 +339,7 @@ BlockRingStoreWrite(
         RingPages = (1 << BlockRing->Order);
         for (Index = 0; Index < RingPages; ++Index) {
             CHAR    Name[MAX_NAME_LEN+1];
-            status = RtlStringCchPrintfA(Name, MAX_NAME_LEN, "ring-ref%d", Index);
+            status = RtlStringCchPrintfA(Name, MAX_NAME_LEN, "ring-ref%u", Index);
             if (!NT_SUCCESS(status))
                 return status;
             status = STORE(Printf, 
index 5508853b69a971d9ac537f2bf13fc6664f0bf542..f592f864232239fb983957a83c4c042887a81a8d 100644 (file)
 #include <ntddk.h>
 #include <stdarg.h>
 
+#ifdef  _SDV_
+#define __MODULE__ ""
+#endif
+
 // DEBUG_FILTER_MASKs
 // Set these to see relevant output
 // ERROR        0x00000001
index 8f53f61cbf99e40086008ef775b57003f639037b..08f9b12d69bb60168d757af85fd745f8d28dc8c0 100644 (file)
@@ -384,6 +384,7 @@ __ScsiAdapterControlTypeName(
     default:                                return "UNKNOWN";
     }
 }
+
 static FORCEINLINE PCHAR
 __ScsiAdapterControlStatus(
     __in SCSI_ADAPTER_CONTROL_STATUS Status
@@ -396,6 +397,8 @@ __ScsiAdapterControlStatus(
     }
 }
 
+HW_INITIALIZE       HwInitialize;
+
 BOOLEAN 
 HwInitialize(
     __in PVOID   HwDeviceExtension
@@ -405,6 +408,8 @@ HwInitialize(
     return TRUE;
 }
 
+HW_INTERRUPT        HwInterrupt;
+
 BOOLEAN 
 HwInterrupt(
     __in PVOID   HwDeviceExtension
@@ -414,6 +419,8 @@ HwInterrupt(
     return TRUE;
 }
 
+HW_RESET_BUS        HwResetBus;
+
 BOOLEAN 
 HwResetBus(
     __in PVOID   HwDeviceExtension,
@@ -427,6 +434,8 @@ HwResetBus(
     return RetVal;
 }
 
+HW_ADAPTER_CONTROL  HwAdapterControl;
+
 SCSI_ADAPTER_CONTROL_STATUS
 HwAdapterControl(
     __in PVOID                       HwDeviceExtension,
@@ -441,6 +450,8 @@ HwAdapterControl(
     return RetVal;
 }
 
+HW_FIND_ADAPTER     HwFindAdapter;
+
 ULONG
 HwFindAdapter(
     IN PVOID                               HwDeviceExtension,
@@ -477,6 +488,9 @@ __FailStorageRequest(
 
     return FALSE;
 }
+
+HW_BUILDIO          HwBuildIo;
+
 BOOLEAN 
 HwBuildIo(
     __in PVOID               HwDeviceExtension,
@@ -489,6 +503,8 @@ HwBuildIo(
     return FdoBuildIo((PXENVBD_FDO)HwDeviceExtension, Srb);
 }
 
+HW_STARTIO          HwStartIo;
+
 BOOLEAN 
 HwStartIo(
     __in PVOID               HwDeviceExtension,
@@ -503,12 +519,10 @@ HwStartIo(
 
 //=============================================================================
 // Driver Redirections
+extern PULONG       InitSafeBootMode;
+
 __drv_dispatchType(IRP_MJ_PNP)
 DRIVER_DISPATCH             DispatchPnp;
-__drv_dispatchType(IRP_MJ_POWER)
-DRIVER_DISPATCH             DispatchPower;
-DRIVER_UNLOAD               DriverUnload;
-DRIVER_INITIALIZE           DriverEntry;
 
 NTSTATUS 
 DispatchPnp(
@@ -546,6 +560,9 @@ DispatchPnp(
     return Status;
 }
 
+__drv_dispatchType(IRP_MJ_POWER)
+DRIVER_DISPATCH             DispatchPower;
+
 NTSTATUS 
 DispatchPower(
     IN PDEVICE_OBJECT   DeviceObject,
@@ -583,6 +600,8 @@ DispatchPower(
     return Status;
 }
 
+DRIVER_UNLOAD               DriverUnload;
+
 VOID
 DriverUnload(
     IN PDRIVER_OBJECT  _DriverObject
@@ -598,10 +617,9 @@ DriverUnload(
     Trace("<=== (Irql=%d)\n", KeGetCurrentIrql());
 }
 
-extern PULONG       InitSafeBootMode;
+DRIVER_INITIALIZE           DriverEntry;
 
 NTSTATUS
-#pragma prefast(suppress:28101, "DriverEntry (XENVBD)")
 DriverEntry(
     IN PDRIVER_OBJECT  _DriverObject,
     IN PUNICODE_STRING RegistryPath
index b21146d6e087c9605e8b68783760be336024fe96..d1fd73e435547df6f4bd064574758dddfd4292d3 100644 (file)
@@ -34,7 +34,7 @@
 
 typedef struct _XENVBD_FDO XENVBD_FDO, *PXENVBD_FDO;
 
-#include <wdm.h>
+#include <ntddk.h>
 #include <xenvbd-storport.h>
 #include "pdo.h"
 #include <store_interface.h>
index b9fbaa2c735641628ad95d0fcf40b2f343494c78..38d70a1c0d2c1d52882d3c83d39434c2f26e8726 100644 (file)
@@ -32,7 +32,7 @@
 #include "frontend.h"
 #include "driver.h"
 #include "fdo.h"
-#include "pdo-inquiry.h"
+#include "pdoinquiry.h"
 #include "srbext.h"
 #include "debug.h"
 #include "assert.h"
diff --git a/src/xenvbd/pdo-inquiry.c b/src/xenvbd/pdo-inquiry.c
deleted file mode 100644 (file)
index d05937e..0000000
+++ /dev/null
@@ -1,555 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */ 
-
-#include "pdo-inquiry.h"
-#include "driver.h"
-#include "debug.h"
-#include "assert.h"
-#include "util.h"
-#include <xencdb.h>
-#include <xenvbd-ntstrsafe.h>
-#include <stdlib.h>
-
-// "00000000-0000-0000-0000-000000000000"
-#define GUID_LENGTH     36 
-
-// 00 00 00 00 00 00 00 00 "XENSRC  00000000"
-#define PAGE83_MIN_SIZE (4 + 4 + 16 + 1)
-
-// 00 00 00 00 + GUID_LENGTH
-#define VDI_ID_LENGTH   (4 + GUID_LENGTH)
-
-#define INQUIRY_POOL_TAG 'qnIX'
-
-typedef struct _XENVBD_PAGE {
-    PCHAR   Data;
-    ULONG   Length;
-} XENVBD_PAGE, *PXENVBD_PAGE;
-
-typedef struct _XENVBD_INQUIRY {
-    XENVBD_PAGE Page80;
-    XENVBD_PAGE Page83;
-    CHAR        VdiUuid[GUID_LENGTH + 1];
-} XENVBD_INQUIRY, *PXENVBD_INQUIRY;
-
-static FORCEINLINE ULONG
-__Min3(
-    __in ULONG  A,
-    __in ULONG  B,
-    __in ULONG  C
-    )
-{
-    return A < B ? __min(A, C) : __min(B, C);
-}
-
-__checkReturn
-__drv_allocatesMem(mem)
-__bcount(Size)
-static FORCEINLINE PVOID 
-#pragma warning(suppress: 28195)
-___InquiryAlloc(
-    __in PCHAR               Caller,
-    __in ULONG               Line,
-    __in SIZE_T              Size
-    )
-{
-    return __AllocateNonPagedPoolWithTag(Caller, Line, Size, INQUIRY_POOL_TAG);
-}
-#define __InquiryAlloc(Size) ___InquiryAlloc(__FUNCTION__, __LINE__, Size)
-
-static FORCEINLINE VOID
-#pragma warning(suppress: 28197)
-__InquiryFree(
-    __in __drv_freesMem(mem) PVOID Buffer
-    )
-{
-    if (Buffer != NULL)
-        __FreePoolWithTag(Buffer, INQUIRY_POOL_TAG);
-}
-
-static FORCEINLINE UCHAR
-__DecodeChar(
-    __in CHAR    Char
-    )
-{
-    if (Char >= 'A' && Char <= 'Z') return Char - 'A';
-    if (Char >= 'a' && Char <= 'z') return Char - 'a' + 26;
-    if (Char >= '0' && Char <= '9') return Char - '0' + 52;
-    if (Char == '+')                return 62;
-    if (Char == '/')                return 63;
-    if (Char == '=')                return 0;
-    return 0xFF;
-}
-static DECLSPEC_NOINLINE UCHAR
-__Decode(
-    __in PUCHAR  Dest,
-    __in PCHAR   Src,
-    __in ULONG   RemainingChars
-    )
-{
-    UCHAR   Values[4]; 
-
-    if (RemainingChars < 4)
-        return 0xFF;
-
-    // take 4 Src chars -> 1, 2, or 3 Dest bytes
-    Values[0] = __DecodeChar(Src[0]);
-    Values[1] = __DecodeChar(Src[1]);
-    Values[2] = __DecodeChar(Src[2]);
-    Values[3] = __DecodeChar(Src[3]);
-
-    // sanity checks
-    if ((Src[0] == '=' || Src[1] == '=') ||
-        (Src[2] == '=' && Src[3] != '='))
-        return 0xFF;
-    if (Values[0] == 0xFF || Values[1] == 0xFF ||
-        Values[2] == 0xFF || Values[3] == 0xFF)
-        return 0xFF;
-
-    // convert
-    Dest[0] = (Values[1] >> 4) | (Values[0] << 2);
-    if (Src[2] == '=')  return 2;
-    Dest[1] = (Values[2] >> 2) | (Values[1] << 4);
-    if (Src[3] == '=')  return 1;
-    Dest[2] = (Values[3]     ) | (Values[2] << 6);
-    return 0;
-}
-__checkReturn
-static NTSTATUS
-__DecodeBase64(
-    __in  PCHAR   Base64,
-    __in  ULONG   Base64Length,
-    __out PVOID   *_Buffer,
-    __out PULONG  BufferLength
-    )
-{
-    // convert Base64(4chars) into Buffer(3bytes)
-    PUCHAR      Buffer;
-    ULONG       NumBlocks;
-    ULONG       i;
-    UCHAR       Pad = 0;
-
-    NumBlocks = Base64Length / 4;
-
-    Buffer = (PUCHAR)__InquiryAlloc(NumBlocks * 3);
-    if (Buffer == NULL) {
-        Error("__InquiryAlloc (STATUS_INSUFFICIENT_RESOURCES)\n");
-        goto fail1;
-    }
-
-    for (i = 0; i < NumBlocks; ++i) {
-        if (Pad)        goto invalid_base64;
-        Pad = __Decode(Buffer + (i * 3), Base64 + (i * 4), Base64Length - (i * 4));
-        if (Pad > 2)    goto invalid_base64;
-    }
-
-    *BufferLength = (NumBlocks * 3) - Pad;
-    *_Buffer = Buffer;
-    return STATUS_SUCCESS;
-
-invalid_base64:
-    Error("Invalid BASE64 encoding\n");
-    __InquiryFree((PVOID)Buffer);
-    return STATUS_UNSUCCESSFUL;
-
-fail1:
-    return STATUS_INSUFFICIENT_RESOURCES;
-}
-static DECLSPEC_NOINLINE BOOLEAN 
-__ReadPage(
-    __in PXENVBD_FRONTEND       Frontend,
-    __in PXENVBD_PAGE           Page,
-    __in PCHAR                  Path
-    )
-{
-    NTSTATUS    Status;
-    PCHAR       Value;
-
-    Status = FrontendStoreReadBackend(Frontend, Path, &Value);
-    if (!NT_SUCCESS(Status))
-        goto fail1;
-
-    Status = __DecodeBase64(Value, (ULONG)strlen(Value), (PVOID*)&Page->Data, &Page->Length);
-    if (!NT_SUCCESS(Status))
-        goto fail2;
-
-    FrontendStoreFree(Frontend, Value);
-    return TRUE;
-
-fail2:
-    FrontendStoreFree(Frontend, Value);
-fail1:
-    Page->Data = NULL;
-    Page->Length = 0;
-    return FALSE;
-}
-
-static FORCEINLINE BOOLEAN
-__HandlePageStd(
-    __in XENVBD_DEVICE_TYPE         DeviceType,
-    __in PSCSI_REQUEST_BLOCK        Srb
-    )
-{
-    PINQUIRYDATA    Data = (PINQUIRYDATA)Srb->DataBuffer;
-    ULONG           Length = Srb->DataTransferLength;
-
-    if (Length < INQUIRYDATABUFFERSIZE)
-        return FALSE;
-
-    switch (DeviceType) {
-    case XENVBD_DEVICE_TYPE_DISK:
-        Data->DeviceType            = DIRECT_ACCESS_DEVICE;
-        Data->DeviceTypeQualifier   = DEVICE_CONNECTED;
-        Data->Versions              = 4;
-        Data->ResponseDataFormat    = 2;
-        Data->AdditionalLength      = INQUIRYDATABUFFERSIZE - 4;
-        Data->CommandQueue          = 1;
-        RtlCopyMemory(Data->VendorId,               "XENSRC  ", 8);
-        RtlCopyMemory(Data->ProductId,              "PVDISK          ", 16);
-        RtlCopyMemory(Data->ProductRevisionLevel,   "2.0 ", 4);
-        break;
-    case XENVBD_DEVICE_TYPE_CDROM:
-        Data->DeviceType            = READ_ONLY_DIRECT_ACCESS_DEVICE;
-        Data->DeviceTypeQualifier   = DEVICE_CONNECTED;
-        Data->RemovableMedia        = TRUE;
-        Data->Versions              = 2;
-        Data->ResponseDataFormat    = 2;
-        Data->Wide32Bit             = TRUE;
-        Data->Synchronous           = TRUE;
-        Data->AdditionalLength      = INQUIRYDATABUFFERSIZE - 4;
-        RtlCopyMemory(Data->VendorId,               "XENSRC  ", 8);
-        RtlCopyMemory(Data->ProductId,              "PVCDROM         ", 16);
-        RtlCopyMemory(Data->ProductRevisionLevel,   "2.0 ", 4);
-        break;
-    default:
-        return FALSE;
-        break;
-    }
-
-    Srb->DataTransferLength = INQUIRYDATABUFFERSIZE;
-    return TRUE;
-}
-static FORCEINLINE BOOLEAN
-__HandlePage00(
-    __in PSCSI_REQUEST_BLOCK        Srb
-    )
-{
-    PCHAR   Data = (PCHAR)Srb->DataBuffer;
-    ULONG   Length = Srb->DataTransferLength;
-
-    if (Length < 7)
-        return FALSE;
-    RtlZeroMemory(Data, Length);
-
-    // 00 00 00 NumPages+1 00 [Page [...]]
-    Data[3] = 3;
-    Data[4] = 0x00;
-    Data[5] = 0x80;
-    Data[6] = 0x83;
-    Srb->DataTransferLength = 7;
-
-    return TRUE;
-}
-static FORCEINLINE BOOLEAN
-__HandlePage80(
-    __in ULONG                      TargetId,
-    __in PXENVBD_INQUIRY            Inquiry,
-    __in PSCSI_REQUEST_BLOCK        Srb
-    )
-{
-    PCHAR   Data = (PCHAR)Srb->DataBuffer;
-    ULONG   Length = Srb->DataTransferLength;
-
-       RtlZeroMemory(Data, Length);
-       if (DriverParameters.SynthesizeInquiry ||
-        Inquiry == NULL || 
-        Inquiry->Page80.Data == NULL || 
-        Inquiry->Page80.Length == 0) {
-        // generate the serial number page
-        PVPD_SERIAL_NUMBER_PAGE Serial;
-        if (Length < sizeof(VPD_SERIAL_NUMBER_PAGE) + 4)
-            return FALSE;
-
-        Serial = (PVPD_SERIAL_NUMBER_PAGE)Data;
-        Serial->PageCode        = 0x80;
-        Serial->PageLength      = 4;
-        (VOID) RtlStringCchPrintfA((PCHAR)Serial->SerialNumber, 5, "%04u", TargetId);
-
-        Verbose("Target[%u] : INQUIRY Using Fake Page80 Data\n", TargetId);
-
-        Srb->DataTransferLength = sizeof(VPD_SERIAL_NUMBER_PAGE) + 4; 
-        // VPD_SERIAL_NUMBER_PAGE includes 1 char already
-    } else {
-        if (Length < Inquiry->Page80.Length)
-            return FALSE;
-
-               RtlCopyMemory(Data, Inquiry->Page80.Data, Inquiry->Page80.Length);
-        Srb->DataTransferLength = Inquiry->Page80.Length;
-    }
-
-    // if possible, append additional data
-    //if (Inquiry && Length >= Srb->DataTransferLength + ADDITIONAL_LENGTH) {
-    //    Srb->DataTransferLength += ADDITIONAL_LENGTH;
-    //}
-    return TRUE;
-}
-static FORCEINLINE BOOLEAN
-__HandlePage83(
-    __in ULONG                      TargetId,
-    __in PXENVBD_INQUIRY            Inquiry,
-    __in PSCSI_REQUEST_BLOCK        Srb
-    )
-{
-    PCHAR   Data = (PCHAR)Srb->DataBuffer;
-    ULONG   Length = Srb->DataTransferLength;
-
-       RtlZeroMemory(Data, Length);
-       if (DriverParameters.SynthesizeInquiry ||
-        Inquiry == NULL || 
-        Inquiry->Page83.Data == NULL || 
-        Inquiry->Page83.Length == 0) {
-        // generate the id page data
-        PVPD_IDENTIFICATION_DESCRIPTOR  Id;
-
-        if (Length < PAGE83_MIN_SIZE)
-            return FALSE;
-
-        Data[1]                 = 0x83;
-        Data[3]                 = 16;
-
-        Id = (PVPD_IDENTIFICATION_DESCRIPTOR)(Data + 4);
-        Id->CodeSet             = VpdCodeSetAscii;
-        Id->IdentifierType      = VpdIdentifierTypeVendorId;
-        Id->IdentifierLength    = 16;
-        (VOID) RtlStringCchPrintfA((PCHAR)Id->Identifier, 17, "XENSRC  %08u", TargetId);
-
-        Verbose("Target[%u] : INQUIRY Using Fake Page83 Data\n", TargetId);
-
-        Srb->DataTransferLength = PAGE83_MIN_SIZE;
-    } else {
-        if (Length < Inquiry->Page83.Length)
-            return FALSE;
-
-        RtlCopyMemory(Data, Inquiry->Page83.Data, Inquiry->Page83.Length);
-        Srb->DataTransferLength = Inquiry->Page83.Length;
-    }
-
-    // if possible, append vdi-uuid as VendorSpecific
-    if (Inquiry && Length >= Srb->DataTransferLength + VDI_ID_LENGTH) {
-        PVPD_IDENTIFICATION_DESCRIPTOR Id;
-        
-        // update internal size
-        *(Data + 3) += VDI_ID_LENGTH;
-
-        // copy new data
-        Id = (PVPD_IDENTIFICATION_DESCRIPTOR)(Data + Srb->DataTransferLength);
-        Id->CodeSet             = VpdCodeSetAscii;
-        Id->IdentifierType      = VpdIdentifierTypeVendorSpecific;
-        Id->IdentifierLength    = GUID_LENGTH;
-        RtlCopyMemory(Id->Identifier, Inquiry->VdiUuid, GUID_LENGTH);        
-        Srb->DataTransferLength += VDI_ID_LENGTH;
-    }
-    return TRUE;
-}
-
-#define MAX_BUFFER      64
-
-static FORCEINLINE VOID
-__TracePage80(
-    __in ULONG                    TargetId,
-    __in PXENVBD_INQUIRY          Inquiry
-    )
-{
-    ULONG           Length;
-    CHAR            Buffer[MAX_BUFFER+1];
-
-    Length = __Min3(Inquiry->Page80.Data[3], MAX_BUFFER, Inquiry->Page80.Length - 4);
-    RtlCopyMemory(Buffer, Inquiry->Page80.Data + 4, Length);
-    Buffer[Length] = 0;
-    Verbose("Target[%u] : SerialNumber = \"%s\"\n", TargetId, Buffer);
-}
-static FORCEINLINE VOID
-__TracePage83(
-    __in ULONG                    TargetId,
-    __in PXENVBD_INQUIRY          Inquiry
-    )
-{
-    ULONG           Length;
-    ULONG           Index;
-    CHAR            Buffer[MAX_BUFFER+1];
-
-    for (Index = 4; Index < Inquiry->Page83.Length; ) {
-        PVPD_IDENTIFICATION_DESCRIPTOR Identifier = (PVPD_IDENTIFICATION_DESCRIPTOR)&Inquiry->Page83.Data[Index];
-
-        switch (Identifier->CodeSet) {
-        case VpdCodeSetAscii:
-            Length = __Min3(Identifier->IdentifierLength, MAX_BUFFER, Inquiry->Page83.Length - Index - 4);
-            RtlCopyMemory(Buffer, Identifier->Identifier, Length);
-            Buffer[Length] = 0;
-            Verbose("Target[%u] : Identifier (ASCII, Type %02x, \"%s\")\n", 
-                    TargetId, Identifier->IdentifierType, Buffer);
-            break;
-
-        default:
-            Verbose("Target[%u] : Identifier (CodeSet %02x, Type %02x, Length %02x)\n", 
-                    TargetId, Identifier->CodeSet, Identifier->IdentifierType, Identifier->IdentifierLength);
-            break;
-        }
-
-        Index += (4 + Identifier->IdentifierLength);
-    }
-}
-
-VOID
-#pragma warning(suppress: 28195)
-PdoReadInquiryData(
-    __in  PXENVBD_FRONTEND        Frontend,
-    __out __drv_allocatesMem(mem) PVOID* _Inquiry
-    )
-{
-    PXENVBD_INQUIRY Inquiry;
-    const CHAR      GuidNull[] = "00000000-0000-0000-0000-000000000000";
-    const ULONG     TargetId = FrontendGetTargetId(Frontend);
-    
-    *_Inquiry = NULL;
-    Inquiry = (PXENVBD_INQUIRY)__InquiryAlloc(sizeof(XENVBD_INQUIRY));
-    if (Inquiry == NULL) {
-        Error("Target[%d] : Memory allocation getting INQUIRY data (%d bytes failed)\n", 
-                TargetId, sizeof(XENVBD_INQUIRY));
-        return;
-    }
-    
-    // initialize VDI-UUID
-    RtlCopyMemory(Inquiry->VdiUuid, GuidNull, GUID_LENGTH);
-    Inquiry->VdiUuid[GUID_LENGTH] = 0;
-
-    // read page80
-    if (!__ReadPage(Frontend, &Inquiry->Page80, "sm-data/scsi/0x12/0x80")) {
-        Warning("Target[%d] : Failed to get Page80 data\n", TargetId);
-    } else {
-        __TracePage80(TargetId, Inquiry);
-    }
-
-    // read page83
-    if (!__ReadPage(Frontend, &Inquiry->Page83, "sm-data/scsi/0x12/0x83")) {
-        Warning("Target[%d] : Failed to get Page83 data\n", TargetId);
-    } else {
-        __TracePage83(TargetId, Inquiry);
-    }
-
-    *_Inquiry = Inquiry;
-}
-
-VOID
-PdoFreeInquiryData(
-    __in __drv_freesMem(mem) PVOID _Inquiry
-    )
-{
-    PXENVBD_INQUIRY Inquiry = (PXENVBD_INQUIRY)_Inquiry;
-
-    if (_Inquiry == NULL)
-        return;
-
-    __InquiryFree((PVOID)Inquiry->Page80.Data);
-    __InquiryFree((PVOID)Inquiry->Page83.Data);
-    __InquiryFree((PVOID)Inquiry);
-}
-
-VOID
-PdoUpdateInquiryData(
-    __in  PXENVBD_FRONTEND       Frontend,
-    __in  PVOID                  _Inquiry
-    )
-{
-    PXENVBD_INQUIRY Inquiry = (PXENVBD_INQUIRY)_Inquiry;
-    NTSTATUS        Status;
-    PCHAR           Value;
-    ULONG           Length;
-    const CHAR      GuidNull[] = "00000000-0000-0000-0000-000000000000";
-
-    if (_Inquiry == NULL)
-        return;
-
-    RtlCopyMemory(Inquiry->VdiUuid, GuidNull, GUID_LENGTH);
-    Inquiry->VdiUuid[GUID_LENGTH] = 0;
-
-    Status = FrontendStoreReadBackend(Frontend, "sm-data/vdi-uuid", &Value);
-    if (NT_SUCCESS(Status)) {
-        Length = (ULONG)strlen(Value);
-
-        if (Length == GUID_LENGTH) {
-            RtlCopyMemory(Inquiry->VdiUuid, Value, Length);
-            Inquiry->VdiUuid[GUID_LENGTH] = 0;
-        }
-
-        FrontendStoreFree(Frontend, Value);
-    }
-
-    Verbose("Target[%u] : VDI-UUID = {%s}\n", FrontendGetTargetId(Frontend), Inquiry->VdiUuid);
-}
-
-VOID
-PdoInquiry(
-    __in ULONG                   TargetId,
-    __in PVOID                   Inquiry,
-    __in PSCSI_REQUEST_BLOCK     Srb,
-    __in XENVBD_DEVICE_TYPE      DeviceType
-    )
-{
-    BOOLEAN         Success;
-    const UCHAR     Evpd = Cdb_EVPD(Srb);
-    const UCHAR     PageCode = Cdb_PageCode(Srb);
-
-    Trace("Target[%d] : INQUIRY %02x%s\n", TargetId, PageCode, Evpd ? " EVPD" : "");
-    if (Evpd) {
-        switch (PageCode) {
-        case 0x00:  Success = __HandlePage00(Srb);                      break;
-        case 0x80:  Success = __HandlePage80(TargetId, (PXENVBD_INQUIRY)Inquiry, Srb);   break;
-        case 0x83:  Success = __HandlePage83(TargetId, (PXENVBD_INQUIRY)Inquiry, Srb);   break;
-        default:    Success = FALSE;                                    break;
-        }
-    } else {
-        switch (PageCode) {
-        case 0x00:  Success = __HandlePageStd(DeviceType, Srb);         break;
-        default:    Success = FALSE;                                    break;
-        }
-    }
-
-    if (Success) {
-        Srb->ScsiStatus = 0; /* SUCCESS */
-        Srb->SrbStatus = SRB_STATUS_SUCCESS;
-    } else {
-        Error("Target[%d] : INQUIRY failed %02x%s\n", TargetId, PageCode, Evpd ? " EVPD" : "");
-        Srb->ScsiStatus = 0x02; /* CHECK_CONDITION */
-        Srb->SrbStatus = SRB_STATUS_ERROR;
-    }
-}
diff --git a/src/xenvbd/pdo-inquiry.h b/src/xenvbd/pdo-inquiry.h
deleted file mode 100644 (file)
index 2f6a7b0..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright (c) Citrix Systems Inc.
- * All rights reserved.
- * 
- * Redistribution and use in source and binary forms, 
- * with or without modification, are permitted provided 
- * that the following conditions are met:
- * 
- * *   Redistributions of source code must retain the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer.
- * *   Redistributions in binary form must reproduce the above 
- *     copyright notice, this list of conditions and the 
- *     following disclaimer in the documentation and/or other 
- *     materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
- * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
- * SUCH DAMAGE.
- */ 
-
-#ifndef _XENVBD_PDO_INQUIRY_H
-#define _XENVBD_PDO_INQUIRY_H
-
-#include <wdm.h>
-#include <xenvbd-storport.h>
-#include "frontend.h"
-
-extern VOID
-PdoReadInquiryData(
-    __in  PXENVBD_FRONTEND        Frontend,
-    __out __drv_allocatesMem(mem) PVOID* _Inquiry
-    );
-
-extern VOID
-PdoFreeInquiryData(
-    __in __drv_freesMem(mem) PVOID Inquiry
-    );
-
-extern VOID
-PdoUpdateInquiryData(
-    __in  PXENVBD_FRONTEND       Frontend,
-    __in  PVOID                  _Inquiry
-    );
-
-extern VOID
-PdoInquiry(
-    __in ULONG                   TargetId,
-    __in PVOID                   Inquiry,
-    __in PSCSI_REQUEST_BLOCK     Srb,
-    __in XENVBD_DEVICE_TYPE      DeviceType
-    );
-
-#endif // _XENVBD_PDO_INQUIRY_H
-
index cd8b21699b5be81454ebb38960775f3a12b3d354..f9e17e97359b9fa0d8c99754a74614eab4d404a8 100644 (file)
@@ -36,7 +36,7 @@
 #include "queue.h"
 #include "srbext.h"
 #include "buffer.h"
-#include "pdo-inquiry.h"
+#include "pdoinquiry.h"
 #include "debug.h"
 #include "assert.h"
 #include "util.h"
index 45b56b6fb4b8403e1c99b85ed3c89454fc2eaf61..6cab59904b64c1c0aed1bc1782963c28f6604f26 100644 (file)
@@ -34,7 +34,7 @@
 
 typedef struct _XENVBD_PDO XENVBD_PDO, *PXENVBD_PDO;
 
-#include <wdm.h>
+#include <ntddk.h>
 #include <xenvbd-storport.h>
 #include "fdo.h"
 #include "srbext.h"
diff --git a/src/xenvbd/pdoinquiry.c b/src/xenvbd/pdoinquiry.c
new file mode 100644 (file)
index 0000000..be7dd84
--- /dev/null
@@ -0,0 +1,555 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */ 
+
+#include "pdoinquiry.h"
+#include "driver.h"
+#include "debug.h"
+#include "assert.h"
+#include "util.h"
+#include <xencdb.h>
+#include <xenvbd-ntstrsafe.h>
+#include <stdlib.h>
+
+// "00000000-0000-0000-0000-000000000000"
+#define GUID_LENGTH     36 
+
+// 00 00 00 00 00 00 00 00 "XENSRC  00000000"
+#define PAGE83_MIN_SIZE (4 + 4 + 16 + 1)
+
+// 00 00 00 00 + GUID_LENGTH
+#define VDI_ID_LENGTH   (4 + GUID_LENGTH)
+
+#define INQUIRY_POOL_TAG 'qnIX'
+
+typedef struct _XENVBD_PAGE {
+    PCHAR   Data;
+    ULONG   Length;
+} XENVBD_PAGE, *PXENVBD_PAGE;
+
+typedef struct _XENVBD_INQUIRY {
+    XENVBD_PAGE Page80;
+    XENVBD_PAGE Page83;
+    CHAR        VdiUuid[GUID_LENGTH + 1];
+} XENVBD_INQUIRY, *PXENVBD_INQUIRY;
+
+static FORCEINLINE ULONG
+__Min3(
+    __in ULONG  A,
+    __in ULONG  B,
+    __in ULONG  C
+    )
+{
+    return A < B ? __min(A, C) : __min(B, C);
+}
+
+__checkReturn
+__drv_allocatesMem(mem)
+__bcount(Size)
+static FORCEINLINE PVOID 
+#pragma warning(suppress: 28195)
+___InquiryAlloc(
+    __in PCHAR               Caller,
+    __in ULONG               Line,
+    __in SIZE_T              Size
+    )
+{
+    return __AllocateNonPagedPoolWithTag(Caller, Line, Size, INQUIRY_POOL_TAG);
+}
+#define __InquiryAlloc(Size) ___InquiryAlloc(__FUNCTION__, __LINE__, Size)
+
+static FORCEINLINE VOID
+#pragma warning(suppress: 28197)
+__InquiryFree(
+    __in __drv_freesMem(mem) PVOID Buffer
+    )
+{
+    if (Buffer != NULL)
+        __FreePoolWithTag(Buffer, INQUIRY_POOL_TAG);
+}
+
+static FORCEINLINE UCHAR
+__DecodeChar(
+    __in CHAR    Char
+    )
+{
+    if (Char >= 'A' && Char <= 'Z') return Char - 'A';
+    if (Char >= 'a' && Char <= 'z') return Char - 'a' + 26;
+    if (Char >= '0' && Char <= '9') return Char - '0' + 52;
+    if (Char == '+')                return 62;
+    if (Char == '/')                return 63;
+    if (Char == '=')                return 0;
+    return 0xFF;
+}
+static DECLSPEC_NOINLINE UCHAR
+__Decode(
+    __in PUCHAR  Dest,
+    __in PCHAR   Src,
+    __in ULONG   RemainingChars
+    )
+{
+    UCHAR   Values[4]; 
+
+    if (RemainingChars < 4)
+        return 0xFF;
+
+    // take 4 Src chars -> 1, 2, or 3 Dest bytes
+    Values[0] = __DecodeChar(Src[0]);
+    Values[1] = __DecodeChar(Src[1]);
+    Values[2] = __DecodeChar(Src[2]);
+    Values[3] = __DecodeChar(Src[3]);
+
+    // sanity checks
+    if ((Src[0] == '=' || Src[1] == '=') ||
+        (Src[2] == '=' && Src[3] != '='))
+        return 0xFF;
+    if (Values[0] == 0xFF || Values[1] == 0xFF ||
+        Values[2] == 0xFF || Values[3] == 0xFF)
+        return 0xFF;
+
+    // convert
+    Dest[0] = (Values[1] >> 4) | (Values[0] << 2);
+    if (Src[2] == '=')  return 2;
+    Dest[1] = (Values[2] >> 2) | (Values[1] << 4);
+    if (Src[3] == '=')  return 1;
+    Dest[2] = (Values[3]     ) | (Values[2] << 6);
+    return 0;
+}
+__checkReturn
+static NTSTATUS
+__DecodeBase64(
+    __in  PCHAR   Base64,
+    __in  ULONG   Base64Length,
+    __out PVOID   *_Buffer,
+    __out PULONG  BufferLength
+    )
+{
+    // convert Base64(4chars) into Buffer(3bytes)
+    PUCHAR      Buffer;
+    ULONG       NumBlocks;
+    ULONG       i;
+    UCHAR       Pad = 0;
+
+    NumBlocks = Base64Length / 4;
+
+    Buffer = (PUCHAR)__InquiryAlloc(NumBlocks * 3);
+    if (Buffer == NULL) {
+        Error("__InquiryAlloc (STATUS_INSUFFICIENT_RESOURCES)\n");
+        goto fail1;
+    }
+
+    for (i = 0; i < NumBlocks; ++i) {
+        if (Pad)        goto invalid_base64;
+        Pad = __Decode(Buffer + (i * 3), Base64 + (i * 4), Base64Length - (i * 4));
+        if (Pad > 2)    goto invalid_base64;
+    }
+
+    *BufferLength = (NumBlocks * 3) - Pad;
+    *_Buffer = Buffer;
+    return STATUS_SUCCESS;
+
+invalid_base64:
+    Error("Invalid BASE64 encoding\n");
+    __InquiryFree((PVOID)Buffer);
+    return STATUS_UNSUCCESSFUL;
+
+fail1:
+    return STATUS_INSUFFICIENT_RESOURCES;
+}
+static DECLSPEC_NOINLINE BOOLEAN 
+__ReadPage(
+    __in PXENVBD_FRONTEND       Frontend,
+    __in PXENVBD_PAGE           Page,
+    __in PCHAR                  Path
+    )
+{
+    NTSTATUS    Status;
+    PCHAR       Value;
+
+    Status = FrontendStoreReadBackend(Frontend, Path, &Value);
+    if (!NT_SUCCESS(Status))
+        goto fail1;
+
+    Status = __DecodeBase64(Value, (ULONG)strlen(Value), (PVOID*)&Page->Data, &Page->Length);
+    if (!NT_SUCCESS(Status))
+        goto fail2;
+
+    FrontendStoreFree(Frontend, Value);
+    return TRUE;
+
+fail2:
+    FrontendStoreFree(Frontend, Value);
+fail1:
+    Page->Data = NULL;
+    Page->Length = 0;
+    return FALSE;
+}
+
+static FORCEINLINE BOOLEAN
+__HandlePageStd(
+    __in XENVBD_DEVICE_TYPE         DeviceType,
+    __in PSCSI_REQUEST_BLOCK        Srb
+    )
+{
+    PINQUIRYDATA    Data = (PINQUIRYDATA)Srb->DataBuffer;
+    ULONG           Length = Srb->DataTransferLength;
+
+    if (Length < INQUIRYDATABUFFERSIZE)
+        return FALSE;
+
+    switch (DeviceType) {
+    case XENVBD_DEVICE_TYPE_DISK:
+        Data->DeviceType            = DIRECT_ACCESS_DEVICE;
+        Data->DeviceTypeQualifier   = DEVICE_CONNECTED;
+        Data->Versions              = 4;
+        Data->ResponseDataFormat    = 2;
+        Data->AdditionalLength      = INQUIRYDATABUFFERSIZE - 4;
+        Data->CommandQueue          = 1;
+        RtlCopyMemory(Data->VendorId,               "XENSRC  ", 8);
+        RtlCopyMemory(Data->ProductId,              "PVDISK          ", 16);
+        RtlCopyMemory(Data->ProductRevisionLevel,   "2.0 ", 4);
+        break;
+    case XENVBD_DEVICE_TYPE_CDROM:
+        Data->DeviceType            = READ_ONLY_DIRECT_ACCESS_DEVICE;
+        Data->DeviceTypeQualifier   = DEVICE_CONNECTED;
+        Data->RemovableMedia        = TRUE;
+        Data->Versions              = 2;
+        Data->ResponseDataFormat    = 2;
+        Data->Wide32Bit             = TRUE;
+        Data->Synchronous           = TRUE;
+        Data->AdditionalLength      = INQUIRYDATABUFFERSIZE - 4;
+        RtlCopyMemory(Data->VendorId,               "XENSRC  ", 8);
+        RtlCopyMemory(Data->ProductId,              "PVCDROM         ", 16);
+        RtlCopyMemory(Data->ProductRevisionLevel,   "2.0 ", 4);
+        break;
+    default:
+        return FALSE;
+        break;
+    }
+
+    Srb->DataTransferLength = INQUIRYDATABUFFERSIZE;
+    return TRUE;
+}
+static FORCEINLINE BOOLEAN
+__HandlePage00(
+    __in PSCSI_REQUEST_BLOCK        Srb
+    )
+{
+    PCHAR   Data = (PCHAR)Srb->DataBuffer;
+    ULONG   Length = Srb->DataTransferLength;
+
+    if (Length < 7)
+        return FALSE;
+    RtlZeroMemory(Data, Length);
+
+    // 00 00 00 NumPages+1 00 [Page [...]]
+    Data[3] = 3;
+    Data[4] = 0x00;
+    Data[5] = 0x80;
+    Data[6] = 0x83;
+    Srb->DataTransferLength = 7;
+
+    return TRUE;
+}
+static FORCEINLINE BOOLEAN
+__HandlePage80(
+    __in ULONG                      TargetId,
+    __in PXENVBD_INQUIRY            Inquiry,
+    __in PSCSI_REQUEST_BLOCK        Srb
+    )
+{
+    PCHAR   Data = (PCHAR)Srb->DataBuffer;
+    ULONG   Length = Srb->DataTransferLength;
+
+       RtlZeroMemory(Data, Length);
+       if (DriverParameters.SynthesizeInquiry ||
+        Inquiry == NULL || 
+        Inquiry->Page80.Data == NULL || 
+        Inquiry->Page80.Length == 0) {
+        // generate the serial number page
+        PVPD_SERIAL_NUMBER_PAGE Serial;
+        if (Length < sizeof(VPD_SERIAL_NUMBER_PAGE) + 4)
+            return FALSE;
+
+        Serial = (PVPD_SERIAL_NUMBER_PAGE)Data;
+        Serial->PageCode        = 0x80;
+        Serial->PageLength      = 4;
+        (VOID) RtlStringCchPrintfA((PCHAR)Serial->SerialNumber, 5, "%04u", TargetId);
+
+        Verbose("Target[%u] : INQUIRY Using Fake Page80 Data\n", TargetId);
+
+        Srb->DataTransferLength = sizeof(VPD_SERIAL_NUMBER_PAGE) + 4; 
+        // VPD_SERIAL_NUMBER_PAGE includes 1 char already
+    } else {
+        if (Length < Inquiry->Page80.Length)
+            return FALSE;
+
+               RtlCopyMemory(Data, Inquiry->Page80.Data, Inquiry->Page80.Length);
+        Srb->DataTransferLength = Inquiry->Page80.Length;
+    }
+
+    // if possible, append additional data
+    //if (Inquiry && Length >= Srb->DataTransferLength + ADDITIONAL_LENGTH) {
+    //    Srb->DataTransferLength += ADDITIONAL_LENGTH;
+    //}
+    return TRUE;
+}
+static FORCEINLINE BOOLEAN
+__HandlePage83(
+    __in ULONG                      TargetId,
+    __in PXENVBD_INQUIRY            Inquiry,
+    __in PSCSI_REQUEST_BLOCK        Srb
+    )
+{
+    PCHAR   Data = (PCHAR)Srb->DataBuffer;
+    ULONG   Length = Srb->DataTransferLength;
+
+       RtlZeroMemory(Data, Length);
+       if (DriverParameters.SynthesizeInquiry ||
+        Inquiry == NULL || 
+        Inquiry->Page83.Data == NULL || 
+        Inquiry->Page83.Length == 0) {
+        // generate the id page data
+        PVPD_IDENTIFICATION_DESCRIPTOR  Id;
+
+        if (Length < PAGE83_MIN_SIZE)
+            return FALSE;
+
+        Data[1]                 = 0x83;
+        Data[3]                 = 16;
+
+        Id = (PVPD_IDENTIFICATION_DESCRIPTOR)(Data + 4);
+        Id->CodeSet             = VpdCodeSetAscii;
+        Id->IdentifierType      = VpdIdentifierTypeVendorId;
+        Id->IdentifierLength    = 16;
+        (VOID) RtlStringCchPrintfA((PCHAR)Id->Identifier, 17, "XENSRC  %08u", TargetId);
+
+        Verbose("Target[%u] : INQUIRY Using Fake Page83 Data\n", TargetId);
+
+        Srb->DataTransferLength = PAGE83_MIN_SIZE;
+    } else {
+        if (Length < Inquiry->Page83.Length)
+            return FALSE;
+
+        RtlCopyMemory(Data, Inquiry->Page83.Data, Inquiry->Page83.Length);
+        Srb->DataTransferLength = Inquiry->Page83.Length;
+    }
+
+    // if possible, append vdi-uuid as VendorSpecific
+    if (Inquiry && Length >= Srb->DataTransferLength + VDI_ID_LENGTH) {
+        PVPD_IDENTIFICATION_DESCRIPTOR Id;
+        
+        // update internal size
+        *(Data + 3) += VDI_ID_LENGTH;
+
+        // copy new data
+        Id = (PVPD_IDENTIFICATION_DESCRIPTOR)(Data + Srb->DataTransferLength);
+        Id->CodeSet             = VpdCodeSetAscii;
+        Id->IdentifierType      = VpdIdentifierTypeVendorSpecific;
+        Id->IdentifierLength    = GUID_LENGTH;
+        RtlCopyMemory(Id->Identifier, Inquiry->VdiUuid, GUID_LENGTH);        
+        Srb->DataTransferLength += VDI_ID_LENGTH;
+    }
+    return TRUE;
+}
+
+#define MAX_BUFFER      64
+
+static FORCEINLINE VOID
+__TracePage80(
+    __in ULONG                    TargetId,
+    __in PXENVBD_INQUIRY          Inquiry
+    )
+{
+    ULONG           Length;
+    CHAR            Buffer[MAX_BUFFER+1];
+
+    Length = __Min3(Inquiry->Page80.Data[3], MAX_BUFFER, Inquiry->Page80.Length - 4);
+    RtlCopyMemory(Buffer, Inquiry->Page80.Data + 4, Length);
+    Buffer[Length] = 0;
+    Verbose("Target[%u] : SerialNumber = \"%s\"\n", TargetId, Buffer);
+}
+static FORCEINLINE VOID
+__TracePage83(
+    __in ULONG                    TargetId,
+    __in PXENVBD_INQUIRY          Inquiry
+    )
+{
+    ULONG           Length;
+    ULONG           Index;
+    CHAR            Buffer[MAX_BUFFER+1];
+
+    for (Index = 4; Index < Inquiry->Page83.Length; ) {
+        PVPD_IDENTIFICATION_DESCRIPTOR Identifier = (PVPD_IDENTIFICATION_DESCRIPTOR)&Inquiry->Page83.Data[Index];
+
+        switch (Identifier->CodeSet) {
+        case VpdCodeSetAscii:
+            Length = __Min3(Identifier->IdentifierLength, MAX_BUFFER, Inquiry->Page83.Length - Index - 4);
+            RtlCopyMemory(Buffer, Identifier->Identifier, Length);
+            Buffer[Length] = 0;
+            Verbose("Target[%u] : Identifier (ASCII, Type %02x, \"%s\")\n", 
+                    TargetId, Identifier->IdentifierType, Buffer);
+            break;
+
+        default:
+            Verbose("Target[%u] : Identifier (CodeSet %02x, Type %02x, Length %02x)\n", 
+                    TargetId, Identifier->CodeSet, Identifier->IdentifierType, Identifier->IdentifierLength);
+            break;
+        }
+
+        Index += (4 + Identifier->IdentifierLength);
+    }
+}
+
+VOID
+#pragma warning(suppress: 28195)
+PdoReadInquiryData(
+    __in  PXENVBD_FRONTEND        Frontend,
+    __out __drv_allocatesMem(mem) PVOID* _Inquiry
+    )
+{
+    PXENVBD_INQUIRY Inquiry;
+    const CHAR      GuidNull[] = "00000000-0000-0000-0000-000000000000";
+    const ULONG     TargetId = FrontendGetTargetId(Frontend);
+    
+    *_Inquiry = NULL;
+    Inquiry = (PXENVBD_INQUIRY)__InquiryAlloc(sizeof(XENVBD_INQUIRY));
+    if (Inquiry == NULL) {
+        Error("Target[%d] : Memory allocation getting INQUIRY data (%d bytes failed)\n", 
+                TargetId, sizeof(XENVBD_INQUIRY));
+        return;
+    }
+    
+    // initialize VDI-UUID
+    RtlCopyMemory(Inquiry->VdiUuid, GuidNull, GUID_LENGTH);
+    Inquiry->VdiUuid[GUID_LENGTH] = 0;
+
+    // read page80
+    if (!__ReadPage(Frontend, &Inquiry->Page80, "sm-data/scsi/0x12/0x80")) {
+        Warning("Target[%d] : Failed to get Page80 data\n", TargetId);
+    } else {
+        __TracePage80(TargetId, Inquiry);
+    }
+
+    // read page83
+    if (!__ReadPage(Frontend, &Inquiry->Page83, "sm-data/scsi/0x12/0x83")) {
+        Warning("Target[%d] : Failed to get Page83 data\n", TargetId);
+    } else {
+        __TracePage83(TargetId, Inquiry);
+    }
+
+    *_Inquiry = Inquiry;
+}
+
+VOID
+PdoFreeInquiryData(
+    __in __drv_freesMem(mem) PVOID _Inquiry
+    )
+{
+    PXENVBD_INQUIRY Inquiry = (PXENVBD_INQUIRY)_Inquiry;
+
+    if (_Inquiry == NULL)
+        return;
+
+    __InquiryFree((PVOID)Inquiry->Page80.Data);
+    __InquiryFree((PVOID)Inquiry->Page83.Data);
+    __InquiryFree((PVOID)Inquiry);
+}
+
+VOID
+PdoUpdateInquiryData(
+    __in  PXENVBD_FRONTEND       Frontend,
+    __in  PVOID                  _Inquiry
+    )
+{
+    PXENVBD_INQUIRY Inquiry = (PXENVBD_INQUIRY)_Inquiry;
+    NTSTATUS        Status;
+    PCHAR           Value;
+    ULONG           Length;
+    const CHAR      GuidNull[] = "00000000-0000-0000-0000-000000000000";
+
+    if (_Inquiry == NULL)
+        return;
+
+    RtlCopyMemory(Inquiry->VdiUuid, GuidNull, GUID_LENGTH);
+    Inquiry->VdiUuid[GUID_LENGTH] = 0;
+
+    Status = FrontendStoreReadBackend(Frontend, "sm-data/vdi-uuid", &Value);
+    if (NT_SUCCESS(Status)) {
+        Length = (ULONG)strlen(Value);
+
+        if (Length == GUID_LENGTH) {
+            RtlCopyMemory(Inquiry->VdiUuid, Value, Length);
+            Inquiry->VdiUuid[GUID_LENGTH] = 0;
+        }
+
+        FrontendStoreFree(Frontend, Value);
+    }
+
+    Verbose("Target[%u] : VDI-UUID = {%s}\n", FrontendGetTargetId(Frontend), Inquiry->VdiUuid);
+}
+
+VOID
+PdoInquiry(
+    __in ULONG                   TargetId,
+    __in PVOID                   Inquiry,
+    __in PSCSI_REQUEST_BLOCK     Srb,
+    __in XENVBD_DEVICE_TYPE      DeviceType
+    )
+{
+    BOOLEAN         Success;
+    const UCHAR     Evpd = Cdb_EVPD(Srb);
+    const UCHAR     PageCode = Cdb_PageCode(Srb);
+
+    Trace("Target[%d] : INQUIRY %02x%s\n", TargetId, PageCode, Evpd ? " EVPD" : "");
+    if (Evpd) {
+        switch (PageCode) {
+        case 0x00:  Success = __HandlePage00(Srb);                      break;
+        case 0x80:  Success = __HandlePage80(TargetId, (PXENVBD_INQUIRY)Inquiry, Srb);   break;
+        case 0x83:  Success = __HandlePage83(TargetId, (PXENVBD_INQUIRY)Inquiry, Srb);   break;
+        default:    Success = FALSE;                                    break;
+        }
+    } else {
+        switch (PageCode) {
+        case 0x00:  Success = __HandlePageStd(DeviceType, Srb);         break;
+        default:    Success = FALSE;                                    break;
+        }
+    }
+
+    if (Success) {
+        Srb->ScsiStatus = 0; /* SUCCESS */
+        Srb->SrbStatus = SRB_STATUS_SUCCESS;
+    } else {
+        Error("Target[%d] : INQUIRY failed %02x%s\n", TargetId, PageCode, Evpd ? " EVPD" : "");
+        Srb->ScsiStatus = 0x02; /* CHECK_CONDITION */
+        Srb->SrbStatus = SRB_STATUS_ERROR;
+    }
+}
diff --git a/src/xenvbd/pdoinquiry.h b/src/xenvbd/pdoinquiry.h
new file mode 100644 (file)
index 0000000..41d7c30
--- /dev/null
@@ -0,0 +1,65 @@
+/* Copyright (c) Citrix Systems Inc.
+ * All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, 
+ * with or without modification, are permitted provided 
+ * that the following conditions are met:
+ * 
+ * *   Redistributions of source code must retain the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer.
+ * *   Redistributions in binary form must reproduce the above 
+ *     copyright notice, this list of conditions and the 
+ *     following disclaimer in the documentation and/or other 
+ *     materials provided with the distribution.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE.
+ */ 
+
+#ifndef _XENVBD_PDO_INQUIRY_H
+#define _XENVBD_PDO_INQUIRY_H
+
+#include <ntddk.h>
+#include <xenvbd-storport.h>
+#include "frontend.h"
+
+extern VOID
+PdoReadInquiryData(
+    __in  PXENVBD_FRONTEND        Frontend,
+    __out __drv_allocatesMem(mem) PVOID* _Inquiry
+    );
+
+extern VOID
+PdoFreeInquiryData(
+    __in __drv_freesMem(mem) PVOID Inquiry
+    );
+
+extern VOID
+PdoUpdateInquiryData(
+    __in  PXENVBD_FRONTEND       Frontend,
+    __in  PVOID                  _Inquiry
+    );
+
+extern VOID
+PdoInquiry(
+    __in ULONG                   TargetId,
+    __in PVOID                   Inquiry,
+    __in PSCSI_REQUEST_BLOCK     Srb,
+    __in XENVBD_DEVICE_TYPE      DeviceType
+    );
+
+#endif // _XENVBD_PDO_INQUIRY_H
+
index 1a4080a9af4578988f6165b9764cc0522b7b16b6..afa663a01b6252a4379fe522446e30bb6fdc29f5 100644 (file)
@@ -32,7 +32,7 @@
 #ifndef _XENVBD_QUEUE_H
 #define _XENVBD_QUEUE_H
 
-#include <wdm.h>
+#include <ntddk.h>
 #include <debug_interface.h>
 
 typedef struct _XENVBD_QUEUE {
index 616d5913fe11fc0fdc53a3e361a5200688fb9f51..bbb965d8657cd3b754e646a6eb78bf99525da75d 100644 (file)
@@ -32,7 +32,7 @@
 #ifndef _XENVBD_SRBEXT_H
 #define _XENVBD_SRBEXT_H
 
-#include <wdm.h>
+#include <ntddk.h>
 #include <xenvbd-storport.h>
 #include <xen.h>
 #include "assert.h"