From 5070d5ec75109df03d093b9056ca9813376874e9 Mon Sep 17 00:00:00 2001 From: soradotwav Date: Thu, 13 Jun 2024 14:08:21 -0700 Subject: [PATCH] Added original v_backup files --- samples/features/sqlvdi/{ => include}/vdi.h | 714 ++++++++------- .../features/sqlvdi/{ => include}/vdierror.h | 0 .../features/sqlvdi/{ => include}/vdiguid.h | 23 +- samples/features/sqlvdi/mprocess/mprocess.cpp | 648 ++++++++++++++ samples/features/sqlvdi/mprocess/mprocess.dsp | 100 +++ samples/features/sqlvdi/mprocess/mprocess.dsw | 29 + samples/features/sqlvdi/mthread/mthread.cpp | 600 +++++++++++++ samples/features/sqlvdi/mthread/mthread.dsp | 100 +++ samples/features/sqlvdi/mthread/mthread.dsw | 29 + samples/features/sqlvdi/osimple/osimple.cpp | 659 ++++++++++++++ samples/features/sqlvdi/osimple/osimple.dsp | 100 +++ samples/features/sqlvdi/osimple/osimple.dsw | 29 + samples/features/sqlvdi/simple/simple.cpp | 348 ++++++++ samples/features/sqlvdi/simple/simple.dsp | 100 +++ samples/features/sqlvdi/simple/simple.dsw | 29 + samples/features/sqlvdi/snapshot/snapshot.cpp | 828 ++++++++++++++++++ samples/features/sqlvdi/snapshot/snapshot.dsp | 100 +++ samples/features/sqlvdi/snapshot/snapshot.dsw | 29 + 18 files changed, 4101 insertions(+), 364 deletions(-) rename samples/features/sqlvdi/{ => include}/vdi.h (74%) rename samples/features/sqlvdi/{ => include}/vdierror.h (100%) rename samples/features/sqlvdi/{ => include}/vdiguid.h (83%) create mode 100644 samples/features/sqlvdi/mprocess/mprocess.cpp create mode 100644 samples/features/sqlvdi/mprocess/mprocess.dsp create mode 100644 samples/features/sqlvdi/mprocess/mprocess.dsw create mode 100644 samples/features/sqlvdi/mthread/mthread.cpp create mode 100644 samples/features/sqlvdi/mthread/mthread.dsp create mode 100644 samples/features/sqlvdi/mthread/mthread.dsw create mode 100644 samples/features/sqlvdi/osimple/osimple.cpp create mode 100644 samples/features/sqlvdi/osimple/osimple.dsp create mode 100644 samples/features/sqlvdi/osimple/osimple.dsw create mode 100644 samples/features/sqlvdi/simple/simple.cpp create mode 100644 samples/features/sqlvdi/simple/simple.dsp create mode 100644 samples/features/sqlvdi/simple/simple.dsw create mode 100644 samples/features/sqlvdi/snapshot/snapshot.cpp create mode 100644 samples/features/sqlvdi/snapshot/snapshot.dsp create mode 100644 samples/features/sqlvdi/snapshot/snapshot.dsw diff --git a/samples/features/sqlvdi/vdi.h b/samples/features/sqlvdi/include/vdi.h similarity index 74% rename from samples/features/sqlvdi/vdi.h rename to samples/features/sqlvdi/include/vdi.h index 97404b79..e7e6f56c 100644 --- a/samples/features/sqlvdi/vdi.h +++ b/samples/features/sqlvdi/include/vdi.h @@ -3,17 +3,25 @@ /* this ALWAYS GENERATED file contains the definitions for the interfaces */ - /* File created by MIDL compiler version 7.00.0555 */ -/* at Tue Oct 12 14:51:44 2010 + /* File created by MIDL compiler version 7.00.0408 */ +/* at Tue Sep 28 18:18:04 2004 */ - +/* Compiler settings for vdi.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) #pragma warning( disable: 4049 ) /* more than 64k source lines */ /* verify that the version is high enough to compile this file*/ #ifndef __REQUIRED_RPCNDR_H_VERSION__ -#define __REQUIRED_RPCNDR_H_VERSION__ 440 +#define __REQUIRED_RPCNDR_H_VERSION__ 475 #endif #include "rpc.h" @@ -35,7 +43,7 @@ #pragma once #endif -/* Forward Declarations */ +/* Forward Declarations */ #ifndef __IClientVirtualDevice_FWD_DEFINED__ #define __IClientVirtualDevice_FWD_DEFINED__ @@ -78,11 +86,13 @@ typedef interface IServerVirtualDeviceSet2 IServerVirtualDeviceSet2; #ifdef __cplusplus extern "C"{ -#endif +#endif +void * __RPC_USER MIDL_user_allocate(size_t); +void __RPC_USER MIDL_user_free( void * ); -/* interface __MIDL_itf_vdi_0000_0000 */ -/* [local] */ +/* interface __MIDL_itf_vdi_0000 */ +/* [local] */ #pragma pack(push, _vdi_h_) @@ -115,10 +125,8 @@ enum VDFeatures VDF_SnapshotPrepare = 0x400, VDF_EnumFrozenFiles = 0x800, VDF_VSSWriter = 0x1000, - VDF_RequestComplete = 0x2000, VDF_WriteMedia = 0x10000, VDF_ReadMedia = 0x20000, - VDF_CompleteEnabled = 0x40000, VDF_LatchStats = 0x80000000, VDF_LikePipe = 0, VDF_LikeTape = ( ( ( ( ( VDF_FileMarks | VDF_Removable ) | VDF_Rewind ) | VDF_Position ) | VDF_SkipBlocks ) | VDF_ReversePosition ) , @@ -142,15 +150,13 @@ enum VDCommands VDC_MountSnapshot = ( VDC_Snapshot + 1 ) , VDC_PrepareToFreeze = ( VDC_MountSnapshot + 1 ) , VDC_FileInfoBegin = ( VDC_PrepareToFreeze + 1 ) , - VDC_FileInfoEnd = ( VDC_FileInfoBegin + 1 ) , - VDC_GetError = (VDC_FileInfoEnd + 1), - VDC_Complete = (VDC_GetError + 1) + VDC_FileInfoEnd = ( VDC_FileInfoBegin + 1 ) } ; enum VDWhence { VDC_Beginning = 0, VDC_Current = ( VDC_Beginning + 1 ) , - VDC_End = ( VDC_Current + 1 ) + VDC_End = ( VDC_Current + 1 ) } ; struct VDC_Command { @@ -161,66 +167,65 @@ struct VDC_Command } ; -extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_0000_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_0000_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_v0_0_s_ifspec; #ifndef __IClientVirtualDevice_INTERFACE_DEFINED__ #define __IClientVirtualDevice_INTERFACE_DEFINED__ /* interface IClientVirtualDevice */ -/* [object][uuid] */ +/* [object][uuid] */ EXTERN_C const IID IID_IClientVirtualDevice; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("40700424-0080-11d2-851f-00c04fc21759") IClientVirtualDevice : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE GetCommand( + virtual HRESULT STDMETHODCALLTYPE GetCommand( /* [in] */ DWORD dwTimeOut, /* [out] */ struct VDC_Command **ppCmd) = 0; - - virtual HRESULT STDMETHODCALLTYPE CompleteCommand( + + virtual HRESULT STDMETHODCALLTYPE CompleteCommand( /* [in] */ struct VDC_Command *pCmd, /* [in] */ DWORD dwCompletionCode, /* [in] */ DWORD dwBytesTransferred, /* [in] */ DWORDLONG dwlPosition) = 0; - + }; - + #else /* C style interface */ typedef struct IClientVirtualDeviceVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IClientVirtualDevice * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( IClientVirtualDevice * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + ULONG ( STDMETHODCALLTYPE *Release )( IClientVirtualDevice * This); - - HRESULT ( STDMETHODCALLTYPE *GetCommand )( + + HRESULT ( STDMETHODCALLTYPE *GetCommand )( IClientVirtualDevice * This, /* [in] */ DWORD dwTimeOut, /* [out] */ struct VDC_Command **ppCmd); - - HRESULT ( STDMETHODCALLTYPE *CompleteCommand )( + + HRESULT ( STDMETHODCALLTYPE *CompleteCommand )( IClientVirtualDevice * This, /* [in] */ struct VDC_Command *pCmd, /* [in] */ DWORD dwCompletionCode, /* [in] */ DWORD dwBytesTransferred, /* [in] */ DWORDLONG dwlPosition); - + END_INTERFACE } IClientVirtualDeviceVtbl; @@ -229,26 +234,26 @@ EXTERN_C const IID IID_IClientVirtualDevice; CONST_VTBL struct IClientVirtualDeviceVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define IClientVirtualDevice_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define IClientVirtualDevice_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define IClientVirtualDevice_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define IClientVirtualDevice_GetCommand(This,dwTimeOut,ppCmd) \ - ( (This)->lpVtbl -> GetCommand(This,dwTimeOut,ppCmd) ) + ( (This)->lpVtbl -> GetCommand(This,dwTimeOut,ppCmd) ) #define IClientVirtualDevice_CompleteCommand(This,pCmd,dwCompletionCode,dwBytesTransferred,dwlPosition) \ - ( (This)->lpVtbl -> CompleteCommand(This,pCmd,dwCompletionCode,dwBytesTransferred,dwlPosition) ) + ( (This)->lpVtbl -> CompleteCommand(This,pCmd,dwCompletionCode,dwBytesTransferred,dwlPosition) ) #endif /* COBJMACROS */ @@ -257,7 +262,7 @@ EXTERN_C const IID IID_IClientVirtualDevice; -HRESULT STDMETHODCALLTYPE IClientVirtualDevice_GetCommand_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDevice_GetCommand_Proxy( IClientVirtualDevice * This, /* [in] */ DWORD dwTimeOut, /* [out] */ struct VDC_Command **ppCmd); @@ -270,7 +275,7 @@ void __RPC_STUB IClientVirtualDevice_GetCommand_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IClientVirtualDevice_CompleteCommand_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDevice_CompleteCommand_Proxy( IClientVirtualDevice * This, /* [in] */ struct VDC_Command *pCmd, /* [in] */ DWORD dwCompletionCode, @@ -293,99 +298,98 @@ void __RPC_STUB IClientVirtualDevice_CompleteCommand_Stub( #define __IClientVirtualDeviceSet_INTERFACE_DEFINED__ /* interface IClientVirtualDeviceSet */ -/* [object][uuid] */ +/* [object][uuid] */ EXTERN_C const IID IID_IClientVirtualDeviceSet; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("40700425-0080-11d2-851f-00c04fc21759") IClientVirtualDeviceSet : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Create( + virtual HRESULT STDMETHODCALLTYPE Create( /* [in] */ LPCWSTR lpName, /* [in] */ struct VDConfig *pCfg) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetConfiguration( + + virtual HRESULT STDMETHODCALLTYPE GetConfiguration( /* [in] */ DWORD dwTimeOut, /* [out] */ struct VDConfig *pCfg) = 0; - - virtual HRESULT STDMETHODCALLTYPE OpenDevice( + + virtual HRESULT STDMETHODCALLTYPE OpenDevice( /* [in] */ LPCWSTR lpName, /* [out] */ IClientVirtualDevice **ppVirtualDevice) = 0; - + virtual HRESULT STDMETHODCALLTYPE Close( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE SignalAbort( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE OpenInSecondary( + + virtual HRESULT STDMETHODCALLTYPE OpenInSecondary( /* [in] */ LPCWSTR lpSetName) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetBufferHandle( + + virtual HRESULT STDMETHODCALLTYPE GetBufferHandle( /* [in] */ BYTE *pBuffer, /* [out] */ DWORD *pBufferHandle) = 0; - - virtual HRESULT STDMETHODCALLTYPE MapBufferHandle( + + virtual HRESULT STDMETHODCALLTYPE MapBufferHandle( /* [in] */ DWORD dwBuffer, /* [out] */ BYTE **ppBuffer) = 0; - + }; - + #else /* C style interface */ typedef struct IClientVirtualDeviceSetVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IClientVirtualDeviceSet * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( IClientVirtualDeviceSet * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + ULONG ( STDMETHODCALLTYPE *Release )( IClientVirtualDeviceSet * This); - - HRESULT ( STDMETHODCALLTYPE *Create )( + + HRESULT ( STDMETHODCALLTYPE *Create )( IClientVirtualDeviceSet * This, /* [in] */ LPCWSTR lpName, /* [in] */ struct VDConfig *pCfg); - - HRESULT ( STDMETHODCALLTYPE *GetConfiguration )( + + HRESULT ( STDMETHODCALLTYPE *GetConfiguration )( IClientVirtualDeviceSet * This, /* [in] */ DWORD dwTimeOut, /* [out] */ struct VDConfig *pCfg); - - HRESULT ( STDMETHODCALLTYPE *OpenDevice )( + + HRESULT ( STDMETHODCALLTYPE *OpenDevice )( IClientVirtualDeviceSet * This, /* [in] */ LPCWSTR lpName, /* [out] */ IClientVirtualDevice **ppVirtualDevice); - - HRESULT ( STDMETHODCALLTYPE *Close )( + + HRESULT ( STDMETHODCALLTYPE *Close )( IClientVirtualDeviceSet * This); - - HRESULT ( STDMETHODCALLTYPE *SignalAbort )( + + HRESULT ( STDMETHODCALLTYPE *SignalAbort )( IClientVirtualDeviceSet * This); - - HRESULT ( STDMETHODCALLTYPE *OpenInSecondary )( + + HRESULT ( STDMETHODCALLTYPE *OpenInSecondary )( IClientVirtualDeviceSet * This, /* [in] */ LPCWSTR lpSetName); - - HRESULT ( STDMETHODCALLTYPE *GetBufferHandle )( + + HRESULT ( STDMETHODCALLTYPE *GetBufferHandle )( IClientVirtualDeviceSet * This, /* [in] */ BYTE *pBuffer, /* [out] */ DWORD *pBufferHandle); - - HRESULT ( STDMETHODCALLTYPE *MapBufferHandle )( + + HRESULT ( STDMETHODCALLTYPE *MapBufferHandle )( IClientVirtualDeviceSet * This, /* [in] */ DWORD dwBuffer, /* [out] */ BYTE **ppBuffer); - + END_INTERFACE } IClientVirtualDeviceSetVtbl; @@ -394,44 +398,44 @@ EXTERN_C const IID IID_IClientVirtualDeviceSet; CONST_VTBL struct IClientVirtualDeviceSetVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define IClientVirtualDeviceSet_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define IClientVirtualDeviceSet_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define IClientVirtualDeviceSet_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define IClientVirtualDeviceSet_Create(This,lpName,pCfg) \ - ( (This)->lpVtbl -> Create(This,lpName,pCfg) ) + ( (This)->lpVtbl -> Create(This,lpName,pCfg) ) #define IClientVirtualDeviceSet_GetConfiguration(This,dwTimeOut,pCfg) \ - ( (This)->lpVtbl -> GetConfiguration(This,dwTimeOut,pCfg) ) + ( (This)->lpVtbl -> GetConfiguration(This,dwTimeOut,pCfg) ) #define IClientVirtualDeviceSet_OpenDevice(This,lpName,ppVirtualDevice) \ - ( (This)->lpVtbl -> OpenDevice(This,lpName,ppVirtualDevice) ) + ( (This)->lpVtbl -> OpenDevice(This,lpName,ppVirtualDevice) ) #define IClientVirtualDeviceSet_Close(This) \ - ( (This)->lpVtbl -> Close(This) ) + ( (This)->lpVtbl -> Close(This) ) #define IClientVirtualDeviceSet_SignalAbort(This) \ - ( (This)->lpVtbl -> SignalAbort(This) ) + ( (This)->lpVtbl -> SignalAbort(This) ) #define IClientVirtualDeviceSet_OpenInSecondary(This,lpSetName) \ - ( (This)->lpVtbl -> OpenInSecondary(This,lpSetName) ) + ( (This)->lpVtbl -> OpenInSecondary(This,lpSetName) ) #define IClientVirtualDeviceSet_GetBufferHandle(This,pBuffer,pBufferHandle) \ - ( (This)->lpVtbl -> GetBufferHandle(This,pBuffer,pBufferHandle) ) + ( (This)->lpVtbl -> GetBufferHandle(This,pBuffer,pBufferHandle) ) #define IClientVirtualDeviceSet_MapBufferHandle(This,dwBuffer,ppBuffer) \ - ( (This)->lpVtbl -> MapBufferHandle(This,dwBuffer,ppBuffer) ) + ( (This)->lpVtbl -> MapBufferHandle(This,dwBuffer,ppBuffer) ) #endif /* COBJMACROS */ @@ -440,7 +444,7 @@ EXTERN_C const IID IID_IClientVirtualDeviceSet; -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_Create_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_Create_Proxy( IClientVirtualDeviceSet * This, /* [in] */ LPCWSTR lpName, /* [in] */ struct VDConfig *pCfg); @@ -453,7 +457,7 @@ void __RPC_STUB IClientVirtualDeviceSet_Create_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_GetConfiguration_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_GetConfiguration_Proxy( IClientVirtualDeviceSet * This, /* [in] */ DWORD dwTimeOut, /* [out] */ struct VDConfig *pCfg); @@ -466,7 +470,7 @@ void __RPC_STUB IClientVirtualDeviceSet_GetConfiguration_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_OpenDevice_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_OpenDevice_Proxy( IClientVirtualDeviceSet * This, /* [in] */ LPCWSTR lpName, /* [out] */ IClientVirtualDevice **ppVirtualDevice); @@ -479,7 +483,7 @@ void __RPC_STUB IClientVirtualDeviceSet_OpenDevice_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_Close_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_Close_Proxy( IClientVirtualDeviceSet * This); @@ -490,7 +494,7 @@ void __RPC_STUB IClientVirtualDeviceSet_Close_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_SignalAbort_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_SignalAbort_Proxy( IClientVirtualDeviceSet * This); @@ -501,7 +505,7 @@ void __RPC_STUB IClientVirtualDeviceSet_SignalAbort_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_OpenInSecondary_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_OpenInSecondary_Proxy( IClientVirtualDeviceSet * This, /* [in] */ LPCWSTR lpSetName); @@ -513,7 +517,7 @@ void __RPC_STUB IClientVirtualDeviceSet_OpenInSecondary_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_GetBufferHandle_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_GetBufferHandle_Proxy( IClientVirtualDeviceSet * This, /* [in] */ BYTE *pBuffer, /* [out] */ DWORD *pBufferHandle); @@ -526,7 +530,7 @@ void __RPC_STUB IClientVirtualDeviceSet_GetBufferHandle_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_MapBufferHandle_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet_MapBufferHandle_Proxy( IClientVirtualDeviceSet * This, /* [in] */ DWORD dwBuffer, /* [out] */ BYTE **ppBuffer); @@ -547,92 +551,91 @@ void __RPC_STUB IClientVirtualDeviceSet_MapBufferHandle_Stub( #define __IClientVirtualDeviceSet2_INTERFACE_DEFINED__ /* interface IClientVirtualDeviceSet2 */ -/* [object][uuid] */ +/* [object][uuid] */ EXTERN_C const IID IID_IClientVirtualDeviceSet2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("d0e6eb07-7a62-11d2-8573-00c04fc21759") IClientVirtualDeviceSet2 : public IClientVirtualDeviceSet { public: - virtual HRESULT STDMETHODCALLTYPE CreateEx( + virtual HRESULT STDMETHODCALLTYPE CreateEx( /* [in] */ LPCWSTR lpInstanceName, /* [in] */ LPCWSTR lpName, /* [in] */ struct VDConfig *pCfg) = 0; - - virtual HRESULT STDMETHODCALLTYPE OpenInSecondaryEx( + + virtual HRESULT STDMETHODCALLTYPE OpenInSecondaryEx( /* [in] */ LPCWSTR lpInstanceName, /* [in] */ LPCWSTR lpSetName) = 0; - + }; - + #else /* C style interface */ typedef struct IClientVirtualDeviceSet2Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IClientVirtualDeviceSet2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( IClientVirtualDeviceSet2 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + ULONG ( STDMETHODCALLTYPE *Release )( IClientVirtualDeviceSet2 * This); - - HRESULT ( STDMETHODCALLTYPE *Create )( + + HRESULT ( STDMETHODCALLTYPE *Create )( IClientVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpName, /* [in] */ struct VDConfig *pCfg); - - HRESULT ( STDMETHODCALLTYPE *GetConfiguration )( + + HRESULT ( STDMETHODCALLTYPE *GetConfiguration )( IClientVirtualDeviceSet2 * This, /* [in] */ DWORD dwTimeOut, /* [out] */ struct VDConfig *pCfg); - - HRESULT ( STDMETHODCALLTYPE *OpenDevice )( + + HRESULT ( STDMETHODCALLTYPE *OpenDevice )( IClientVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpName, /* [out] */ IClientVirtualDevice **ppVirtualDevice); - - HRESULT ( STDMETHODCALLTYPE *Close )( + + HRESULT ( STDMETHODCALLTYPE *Close )( IClientVirtualDeviceSet2 * This); - - HRESULT ( STDMETHODCALLTYPE *SignalAbort )( + + HRESULT ( STDMETHODCALLTYPE *SignalAbort )( IClientVirtualDeviceSet2 * This); - - HRESULT ( STDMETHODCALLTYPE *OpenInSecondary )( + + HRESULT ( STDMETHODCALLTYPE *OpenInSecondary )( IClientVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpSetName); - - HRESULT ( STDMETHODCALLTYPE *GetBufferHandle )( + + HRESULT ( STDMETHODCALLTYPE *GetBufferHandle )( IClientVirtualDeviceSet2 * This, /* [in] */ BYTE *pBuffer, /* [out] */ DWORD *pBufferHandle); - - HRESULT ( STDMETHODCALLTYPE *MapBufferHandle )( + + HRESULT ( STDMETHODCALLTYPE *MapBufferHandle )( IClientVirtualDeviceSet2 * This, /* [in] */ DWORD dwBuffer, /* [out] */ BYTE **ppBuffer); - - HRESULT ( STDMETHODCALLTYPE *CreateEx )( + + HRESULT ( STDMETHODCALLTYPE *CreateEx )( IClientVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpInstanceName, /* [in] */ LPCWSTR lpName, /* [in] */ struct VDConfig *pCfg); - - HRESULT ( STDMETHODCALLTYPE *OpenInSecondaryEx )( + + HRESULT ( STDMETHODCALLTYPE *OpenInSecondaryEx )( IClientVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpInstanceName, /* [in] */ LPCWSTR lpSetName); - + END_INTERFACE } IClientVirtualDeviceSet2Vtbl; @@ -641,51 +644,51 @@ EXTERN_C const IID IID_IClientVirtualDeviceSet2; CONST_VTBL struct IClientVirtualDeviceSet2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define IClientVirtualDeviceSet2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define IClientVirtualDeviceSet2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define IClientVirtualDeviceSet2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define IClientVirtualDeviceSet2_Create(This,lpName,pCfg) \ - ( (This)->lpVtbl -> Create(This,lpName,pCfg) ) + ( (This)->lpVtbl -> Create(This,lpName,pCfg) ) #define IClientVirtualDeviceSet2_GetConfiguration(This,dwTimeOut,pCfg) \ - ( (This)->lpVtbl -> GetConfiguration(This,dwTimeOut,pCfg) ) + ( (This)->lpVtbl -> GetConfiguration(This,dwTimeOut,pCfg) ) #define IClientVirtualDeviceSet2_OpenDevice(This,lpName,ppVirtualDevice) \ - ( (This)->lpVtbl -> OpenDevice(This,lpName,ppVirtualDevice) ) + ( (This)->lpVtbl -> OpenDevice(This,lpName,ppVirtualDevice) ) #define IClientVirtualDeviceSet2_Close(This) \ - ( (This)->lpVtbl -> Close(This) ) + ( (This)->lpVtbl -> Close(This) ) #define IClientVirtualDeviceSet2_SignalAbort(This) \ - ( (This)->lpVtbl -> SignalAbort(This) ) + ( (This)->lpVtbl -> SignalAbort(This) ) #define IClientVirtualDeviceSet2_OpenInSecondary(This,lpSetName) \ - ( (This)->lpVtbl -> OpenInSecondary(This,lpSetName) ) + ( (This)->lpVtbl -> OpenInSecondary(This,lpSetName) ) #define IClientVirtualDeviceSet2_GetBufferHandle(This,pBuffer,pBufferHandle) \ - ( (This)->lpVtbl -> GetBufferHandle(This,pBuffer,pBufferHandle) ) + ( (This)->lpVtbl -> GetBufferHandle(This,pBuffer,pBufferHandle) ) #define IClientVirtualDeviceSet2_MapBufferHandle(This,dwBuffer,ppBuffer) \ - ( (This)->lpVtbl -> MapBufferHandle(This,dwBuffer,ppBuffer) ) + ( (This)->lpVtbl -> MapBufferHandle(This,dwBuffer,ppBuffer) ) #define IClientVirtualDeviceSet2_CreateEx(This,lpInstanceName,lpName,pCfg) \ - ( (This)->lpVtbl -> CreateEx(This,lpInstanceName,lpName,pCfg) ) + ( (This)->lpVtbl -> CreateEx(This,lpInstanceName,lpName,pCfg) ) #define IClientVirtualDeviceSet2_OpenInSecondaryEx(This,lpInstanceName,lpSetName) \ - ( (This)->lpVtbl -> OpenInSecondaryEx(This,lpInstanceName,lpSetName) ) + ( (This)->lpVtbl -> OpenInSecondaryEx(This,lpInstanceName,lpSetName) ) #endif /* COBJMACROS */ @@ -694,7 +697,7 @@ EXTERN_C const IID IID_IClientVirtualDeviceSet2; -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet2_CreateEx_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet2_CreateEx_Proxy( IClientVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpInstanceName, /* [in] */ LPCWSTR lpName, @@ -708,7 +711,7 @@ void __RPC_STUB IClientVirtualDeviceSet2_CreateEx_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet2_OpenInSecondaryEx_Proxy( +HRESULT STDMETHODCALLTYPE IClientVirtualDeviceSet2_OpenInSecondaryEx_Proxy( IClientVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpInstanceName, /* [in] */ LPCWSTR lpSetName); @@ -725,8 +728,8 @@ void __RPC_STUB IClientVirtualDeviceSet2_OpenInSecondaryEx_Stub( #endif /* __IClientVirtualDeviceSet2_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_vdi_0000_0003 */ -/* [local] */ +/* interface __MIDL_itf_vdi_0011 */ +/* [local] */ struct VDS_Command { @@ -742,56 +745,55 @@ struct VDS_Command } ; -extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_0003_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_0003_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_vdi_0011_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_vdi_0011_v0_0_s_ifspec; #ifndef __IServerVirtualDevice_INTERFACE_DEFINED__ #define __IServerVirtualDevice_INTERFACE_DEFINED__ /* interface IServerVirtualDevice */ -/* [object][uuid] */ +/* [object][uuid] */ EXTERN_C const IID IID_IServerVirtualDevice; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("b5e7a131-a7bd-11d1-84c2-00c04fc21759") IServerVirtualDevice : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE SendCommand( + virtual HRESULT STDMETHODCALLTYPE SendCommand( /* [in] */ struct VDS_Command *pCmd) = 0; - + virtual HRESULT STDMETHODCALLTYPE CloseDevice( void) = 0; - + }; - + #else /* C style interface */ typedef struct IServerVirtualDeviceVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IServerVirtualDevice * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( IServerVirtualDevice * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + ULONG ( STDMETHODCALLTYPE *Release )( IServerVirtualDevice * This); - - HRESULT ( STDMETHODCALLTYPE *SendCommand )( + + HRESULT ( STDMETHODCALLTYPE *SendCommand )( IServerVirtualDevice * This, /* [in] */ struct VDS_Command *pCmd); - - HRESULT ( STDMETHODCALLTYPE *CloseDevice )( + + HRESULT ( STDMETHODCALLTYPE *CloseDevice )( IServerVirtualDevice * This); - + END_INTERFACE } IServerVirtualDeviceVtbl; @@ -800,26 +802,26 @@ EXTERN_C const IID IID_IServerVirtualDevice; CONST_VTBL struct IServerVirtualDeviceVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define IServerVirtualDevice_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define IServerVirtualDevice_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define IServerVirtualDevice_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define IServerVirtualDevice_SendCommand(This,pCmd) \ - ( (This)->lpVtbl -> SendCommand(This,pCmd) ) + ( (This)->lpVtbl -> SendCommand(This,pCmd) ) #define IServerVirtualDevice_CloseDevice(This) \ - ( (This)->lpVtbl -> CloseDevice(This) ) + ( (This)->lpVtbl -> CloseDevice(This) ) #endif /* COBJMACROS */ @@ -828,7 +830,7 @@ EXTERN_C const IID IID_IServerVirtualDevice; -HRESULT STDMETHODCALLTYPE IServerVirtualDevice_SendCommand_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDevice_SendCommand_Proxy( IServerVirtualDevice * This, /* [in] */ struct VDS_Command *pCmd); @@ -840,7 +842,7 @@ void __RPC_STUB IServerVirtualDevice_SendCommand_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDevice_CloseDevice_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDevice_CloseDevice_Proxy( IServerVirtualDevice * This); @@ -859,109 +861,108 @@ void __RPC_STUB IServerVirtualDevice_CloseDevice_Stub( #define __IServerVirtualDeviceSet_INTERFACE_DEFINED__ /* interface IServerVirtualDeviceSet */ -/* [object][uuid] */ +/* [object][uuid] */ EXTERN_C const IID IID_IServerVirtualDeviceSet; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("b5e7a132-a7bd-11d1-84c2-00c04fc21759") IServerVirtualDeviceSet : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Open( + virtual HRESULT STDMETHODCALLTYPE Open( /* [in] */ LPCWSTR lpName) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetConfiguration( + + virtual HRESULT STDMETHODCALLTYPE GetConfiguration( /* [out] */ struct VDConfig *pCfg) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetConfiguration( + + virtual HRESULT STDMETHODCALLTYPE SetConfiguration( /* [in] */ struct VDConfig *pCfg) = 0; - + virtual HRESULT STDMETHODCALLTYPE ExecuteCompletionAgent( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE OpenDevice( + + virtual HRESULT STDMETHODCALLTYPE OpenDevice( /* [in] */ LPCWSTR lpName, /* [out] */ IServerVirtualDevice **ppVirtualDevice) = 0; - - virtual HRESULT STDMETHODCALLTYPE AllocateBuffer( + + virtual HRESULT STDMETHODCALLTYPE AllocateBuffer( /* [out] */ BYTE **ppBuffer, /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment) = 0; - - virtual HRESULT STDMETHODCALLTYPE FreeBuffer( + + virtual HRESULT STDMETHODCALLTYPE FreeBuffer( /* [in] */ BYTE *pBuffer, /* [in] */ DWORD dwSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsSharedBuffer( + + virtual HRESULT STDMETHODCALLTYPE IsSharedBuffer( /* [in] */ BYTE *pBuffer) = 0; - + virtual HRESULT STDMETHODCALLTYPE SignalAbort( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE Close( void) = 0; - + }; - + #else /* C style interface */ typedef struct IServerVirtualDeviceSetVtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IServerVirtualDeviceSet * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( IServerVirtualDeviceSet * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + ULONG ( STDMETHODCALLTYPE *Release )( IServerVirtualDeviceSet * This); - - HRESULT ( STDMETHODCALLTYPE *Open )( + + HRESULT ( STDMETHODCALLTYPE *Open )( IServerVirtualDeviceSet * This, /* [in] */ LPCWSTR lpName); - - HRESULT ( STDMETHODCALLTYPE *GetConfiguration )( + + HRESULT ( STDMETHODCALLTYPE *GetConfiguration )( IServerVirtualDeviceSet * This, /* [out] */ struct VDConfig *pCfg); - - HRESULT ( STDMETHODCALLTYPE *SetConfiguration )( + + HRESULT ( STDMETHODCALLTYPE *SetConfiguration )( IServerVirtualDeviceSet * This, /* [in] */ struct VDConfig *pCfg); - - HRESULT ( STDMETHODCALLTYPE *ExecuteCompletionAgent )( + + HRESULT ( STDMETHODCALLTYPE *ExecuteCompletionAgent )( IServerVirtualDeviceSet * This); - - HRESULT ( STDMETHODCALLTYPE *OpenDevice )( + + HRESULT ( STDMETHODCALLTYPE *OpenDevice )( IServerVirtualDeviceSet * This, /* [in] */ LPCWSTR lpName, /* [out] */ IServerVirtualDevice **ppVirtualDevice); - - HRESULT ( STDMETHODCALLTYPE *AllocateBuffer )( + + HRESULT ( STDMETHODCALLTYPE *AllocateBuffer )( IServerVirtualDeviceSet * This, /* [out] */ BYTE **ppBuffer, /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment); - - HRESULT ( STDMETHODCALLTYPE *FreeBuffer )( + + HRESULT ( STDMETHODCALLTYPE *FreeBuffer )( IServerVirtualDeviceSet * This, /* [in] */ BYTE *pBuffer, /* [in] */ DWORD dwSize); - - HRESULT ( STDMETHODCALLTYPE *IsSharedBuffer )( + + HRESULT ( STDMETHODCALLTYPE *IsSharedBuffer )( IServerVirtualDeviceSet * This, /* [in] */ BYTE *pBuffer); - - HRESULT ( STDMETHODCALLTYPE *SignalAbort )( + + HRESULT ( STDMETHODCALLTYPE *SignalAbort )( IServerVirtualDeviceSet * This); - - HRESULT ( STDMETHODCALLTYPE *Close )( + + HRESULT ( STDMETHODCALLTYPE *Close )( IServerVirtualDeviceSet * This); - + END_INTERFACE } IServerVirtualDeviceSetVtbl; @@ -970,50 +971,50 @@ EXTERN_C const IID IID_IServerVirtualDeviceSet; CONST_VTBL struct IServerVirtualDeviceSetVtbl *lpVtbl; }; - + #ifdef COBJMACROS #define IServerVirtualDeviceSet_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define IServerVirtualDeviceSet_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define IServerVirtualDeviceSet_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define IServerVirtualDeviceSet_Open(This,lpName) \ - ( (This)->lpVtbl -> Open(This,lpName) ) + ( (This)->lpVtbl -> Open(This,lpName) ) #define IServerVirtualDeviceSet_GetConfiguration(This,pCfg) \ - ( (This)->lpVtbl -> GetConfiguration(This,pCfg) ) + ( (This)->lpVtbl -> GetConfiguration(This,pCfg) ) #define IServerVirtualDeviceSet_SetConfiguration(This,pCfg) \ - ( (This)->lpVtbl -> SetConfiguration(This,pCfg) ) + ( (This)->lpVtbl -> SetConfiguration(This,pCfg) ) #define IServerVirtualDeviceSet_ExecuteCompletionAgent(This) \ - ( (This)->lpVtbl -> ExecuteCompletionAgent(This) ) + ( (This)->lpVtbl -> ExecuteCompletionAgent(This) ) #define IServerVirtualDeviceSet_OpenDevice(This,lpName,ppVirtualDevice) \ - ( (This)->lpVtbl -> OpenDevice(This,lpName,ppVirtualDevice) ) + ( (This)->lpVtbl -> OpenDevice(This,lpName,ppVirtualDevice) ) #define IServerVirtualDeviceSet_AllocateBuffer(This,ppBuffer,dwSize,dwAlignment) \ - ( (This)->lpVtbl -> AllocateBuffer(This,ppBuffer,dwSize,dwAlignment) ) + ( (This)->lpVtbl -> AllocateBuffer(This,ppBuffer,dwSize,dwAlignment) ) #define IServerVirtualDeviceSet_FreeBuffer(This,pBuffer,dwSize) \ - ( (This)->lpVtbl -> FreeBuffer(This,pBuffer,dwSize) ) + ( (This)->lpVtbl -> FreeBuffer(This,pBuffer,dwSize) ) #define IServerVirtualDeviceSet_IsSharedBuffer(This,pBuffer) \ - ( (This)->lpVtbl -> IsSharedBuffer(This,pBuffer) ) + ( (This)->lpVtbl -> IsSharedBuffer(This,pBuffer) ) #define IServerVirtualDeviceSet_SignalAbort(This) \ - ( (This)->lpVtbl -> SignalAbort(This) ) + ( (This)->lpVtbl -> SignalAbort(This) ) #define IServerVirtualDeviceSet_Close(This) \ - ( (This)->lpVtbl -> Close(This) ) + ( (This)->lpVtbl -> Close(This) ) #endif /* COBJMACROS */ @@ -1022,7 +1023,7 @@ EXTERN_C const IID IID_IServerVirtualDeviceSet; -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_Open_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_Open_Proxy( IServerVirtualDeviceSet * This, /* [in] */ LPCWSTR lpName); @@ -1034,7 +1035,7 @@ void __RPC_STUB IServerVirtualDeviceSet_Open_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_GetConfiguration_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_GetConfiguration_Proxy( IServerVirtualDeviceSet * This, /* [out] */ struct VDConfig *pCfg); @@ -1046,7 +1047,7 @@ void __RPC_STUB IServerVirtualDeviceSet_GetConfiguration_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_SetConfiguration_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_SetConfiguration_Proxy( IServerVirtualDeviceSet * This, /* [in] */ struct VDConfig *pCfg); @@ -1058,7 +1059,7 @@ void __RPC_STUB IServerVirtualDeviceSet_SetConfiguration_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_ExecuteCompletionAgent_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_ExecuteCompletionAgent_Proxy( IServerVirtualDeviceSet * This); @@ -1069,7 +1070,7 @@ void __RPC_STUB IServerVirtualDeviceSet_ExecuteCompletionAgent_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_OpenDevice_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_OpenDevice_Proxy( IServerVirtualDeviceSet * This, /* [in] */ LPCWSTR lpName, /* [out] */ IServerVirtualDevice **ppVirtualDevice); @@ -1082,7 +1083,7 @@ void __RPC_STUB IServerVirtualDeviceSet_OpenDevice_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_AllocateBuffer_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_AllocateBuffer_Proxy( IServerVirtualDeviceSet * This, /* [out] */ BYTE **ppBuffer, /* [in] */ DWORD dwSize, @@ -1096,7 +1097,7 @@ void __RPC_STUB IServerVirtualDeviceSet_AllocateBuffer_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_FreeBuffer_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_FreeBuffer_Proxy( IServerVirtualDeviceSet * This, /* [in] */ BYTE *pBuffer, /* [in] */ DWORD dwSize); @@ -1109,7 +1110,7 @@ void __RPC_STUB IServerVirtualDeviceSet_FreeBuffer_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_IsSharedBuffer_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_IsSharedBuffer_Proxy( IServerVirtualDeviceSet * This, /* [in] */ BYTE *pBuffer); @@ -1121,7 +1122,7 @@ void __RPC_STUB IServerVirtualDeviceSet_IsSharedBuffer_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_SignalAbort_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_SignalAbort_Proxy( IServerVirtualDeviceSet * This); @@ -1132,7 +1133,7 @@ void __RPC_STUB IServerVirtualDeviceSet_SignalAbort_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_Close_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet_Close_Proxy( IServerVirtualDeviceSet * This); @@ -1151,146 +1152,145 @@ void __RPC_STUB IServerVirtualDeviceSet_Close_Stub( #define __IServerVirtualDeviceSet2_INTERFACE_DEFINED__ /* interface IServerVirtualDeviceSet2 */ -/* [object][uuid] */ +/* [object][uuid] */ EXTERN_C const IID IID_IServerVirtualDeviceSet2; #if defined(__cplusplus) && !defined(CINTERFACE) - + MIDL_INTERFACE("AECBD0D6-24C6-11d3-85B7-00C04FC21759") IServerVirtualDeviceSet2 : public IUnknown { public: - virtual HRESULT STDMETHODCALLTYPE Open( + virtual HRESULT STDMETHODCALLTYPE Open( /* [in] */ LPCWSTR lpInstanceName, /* [in] */ LPCWSTR lpSetName) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetConfiguration( + + virtual HRESULT STDMETHODCALLTYPE GetConfiguration( /* [out] */ struct VDConfig *pCfg) = 0; - - virtual HRESULT STDMETHODCALLTYPE BeginConfiguration( + + virtual HRESULT STDMETHODCALLTYPE BeginConfiguration( /* [in] */ DWORD dwFeatures, /* [in] */ DWORD dwBlockSize, /* [in] */ DWORD dwAlignment, /* [in] */ DWORD dwMaxTransferSize, /* [in] */ DWORD dwTimeout) = 0; - + virtual HRESULT STDMETHODCALLTYPE EndConfiguration( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE RequestBuffers( + + virtual HRESULT STDMETHODCALLTYPE RequestBuffers( /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment, /* [in] */ DWORD dwCount) = 0; - - virtual HRESULT STDMETHODCALLTYPE QueryAvailableBuffers( + + virtual HRESULT STDMETHODCALLTYPE QueryAvailableBuffers( /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment, /* [out] */ DWORD *pCount) = 0; - + virtual HRESULT STDMETHODCALLTYPE ExecuteCompletionAgent( void) = 0; - - virtual HRESULT STDMETHODCALLTYPE OpenDevice( + + virtual HRESULT STDMETHODCALLTYPE OpenDevice( /* [in] */ LPCWSTR lpName, /* [out] */ IServerVirtualDevice **ppVirtualDevice) = 0; - - virtual HRESULT STDMETHODCALLTYPE AllocateBuffer( + + virtual HRESULT STDMETHODCALLTYPE AllocateBuffer( /* [out] */ BYTE **ppBuffer, /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment) = 0; - - virtual HRESULT STDMETHODCALLTYPE FreeBuffer( + + virtual HRESULT STDMETHODCALLTYPE FreeBuffer( /* [in] */ BYTE *pBuffer, /* [in] */ DWORD dwSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE IsSharedBuffer( + + virtual HRESULT STDMETHODCALLTYPE IsSharedBuffer( /* [in] */ BYTE *pBuffer) = 0; - + virtual HRESULT STDMETHODCALLTYPE SignalAbort( void) = 0; - + virtual HRESULT STDMETHODCALLTYPE Close( void) = 0; - + }; - + #else /* C style interface */ typedef struct IServerVirtualDeviceSet2Vtbl { BEGIN_INTERFACE - - HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( IServerVirtualDeviceSet2 * This, /* [in] */ REFIID riid, - /* [annotation][iid_is][out] */ - __RPC__deref_out void **ppvObject); - - ULONG ( STDMETHODCALLTYPE *AddRef )( + /* [iid_is][out] */ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( IServerVirtualDeviceSet2 * This); - - ULONG ( STDMETHODCALLTYPE *Release )( + + ULONG ( STDMETHODCALLTYPE *Release )( IServerVirtualDeviceSet2 * This); - - HRESULT ( STDMETHODCALLTYPE *Open )( + + HRESULT ( STDMETHODCALLTYPE *Open )( IServerVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpInstanceName, /* [in] */ LPCWSTR lpSetName); - - HRESULT ( STDMETHODCALLTYPE *GetConfiguration )( + + HRESULT ( STDMETHODCALLTYPE *GetConfiguration )( IServerVirtualDeviceSet2 * This, /* [out] */ struct VDConfig *pCfg); - - HRESULT ( STDMETHODCALLTYPE *BeginConfiguration )( + + HRESULT ( STDMETHODCALLTYPE *BeginConfiguration )( IServerVirtualDeviceSet2 * This, /* [in] */ DWORD dwFeatures, /* [in] */ DWORD dwBlockSize, /* [in] */ DWORD dwAlignment, /* [in] */ DWORD dwMaxTransferSize, /* [in] */ DWORD dwTimeout); - - HRESULT ( STDMETHODCALLTYPE *EndConfiguration )( + + HRESULT ( STDMETHODCALLTYPE *EndConfiguration )( IServerVirtualDeviceSet2 * This); - - HRESULT ( STDMETHODCALLTYPE *RequestBuffers )( + + HRESULT ( STDMETHODCALLTYPE *RequestBuffers )( IServerVirtualDeviceSet2 * This, /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment, /* [in] */ DWORD dwCount); - - HRESULT ( STDMETHODCALLTYPE *QueryAvailableBuffers )( + + HRESULT ( STDMETHODCALLTYPE *QueryAvailableBuffers )( IServerVirtualDeviceSet2 * This, /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment, /* [out] */ DWORD *pCount); - - HRESULT ( STDMETHODCALLTYPE *ExecuteCompletionAgent )( + + HRESULT ( STDMETHODCALLTYPE *ExecuteCompletionAgent )( IServerVirtualDeviceSet2 * This); - - HRESULT ( STDMETHODCALLTYPE *OpenDevice )( + + HRESULT ( STDMETHODCALLTYPE *OpenDevice )( IServerVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpName, /* [out] */ IServerVirtualDevice **ppVirtualDevice); - - HRESULT ( STDMETHODCALLTYPE *AllocateBuffer )( + + HRESULT ( STDMETHODCALLTYPE *AllocateBuffer )( IServerVirtualDeviceSet2 * This, /* [out] */ BYTE **ppBuffer, /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment); - - HRESULT ( STDMETHODCALLTYPE *FreeBuffer )( + + HRESULT ( STDMETHODCALLTYPE *FreeBuffer )( IServerVirtualDeviceSet2 * This, /* [in] */ BYTE *pBuffer, /* [in] */ DWORD dwSize); - - HRESULT ( STDMETHODCALLTYPE *IsSharedBuffer )( + + HRESULT ( STDMETHODCALLTYPE *IsSharedBuffer )( IServerVirtualDeviceSet2 * This, /* [in] */ BYTE *pBuffer); - - HRESULT ( STDMETHODCALLTYPE *SignalAbort )( + + HRESULT ( STDMETHODCALLTYPE *SignalAbort )( IServerVirtualDeviceSet2 * This); - - HRESULT ( STDMETHODCALLTYPE *Close )( + + HRESULT ( STDMETHODCALLTYPE *Close )( IServerVirtualDeviceSet2 * This); - + END_INTERFACE } IServerVirtualDeviceSet2Vtbl; @@ -1299,59 +1299,59 @@ EXTERN_C const IID IID_IServerVirtualDeviceSet2; CONST_VTBL struct IServerVirtualDeviceSet2Vtbl *lpVtbl; }; - + #ifdef COBJMACROS #define IServerVirtualDeviceSet2_QueryInterface(This,riid,ppvObject) \ - ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) #define IServerVirtualDeviceSet2_AddRef(This) \ - ( (This)->lpVtbl -> AddRef(This) ) + ( (This)->lpVtbl -> AddRef(This) ) #define IServerVirtualDeviceSet2_Release(This) \ - ( (This)->lpVtbl -> Release(This) ) + ( (This)->lpVtbl -> Release(This) ) #define IServerVirtualDeviceSet2_Open(This,lpInstanceName,lpSetName) \ - ( (This)->lpVtbl -> Open(This,lpInstanceName,lpSetName) ) + ( (This)->lpVtbl -> Open(This,lpInstanceName,lpSetName) ) #define IServerVirtualDeviceSet2_GetConfiguration(This,pCfg) \ - ( (This)->lpVtbl -> GetConfiguration(This,pCfg) ) + ( (This)->lpVtbl -> GetConfiguration(This,pCfg) ) #define IServerVirtualDeviceSet2_BeginConfiguration(This,dwFeatures,dwBlockSize,dwAlignment,dwMaxTransferSize,dwTimeout) \ - ( (This)->lpVtbl -> BeginConfiguration(This,dwFeatures,dwBlockSize,dwAlignment,dwMaxTransferSize,dwTimeout) ) + ( (This)->lpVtbl -> BeginConfiguration(This,dwFeatures,dwBlockSize,dwAlignment,dwMaxTransferSize,dwTimeout) ) #define IServerVirtualDeviceSet2_EndConfiguration(This) \ - ( (This)->lpVtbl -> EndConfiguration(This) ) + ( (This)->lpVtbl -> EndConfiguration(This) ) #define IServerVirtualDeviceSet2_RequestBuffers(This,dwSize,dwAlignment,dwCount) \ - ( (This)->lpVtbl -> RequestBuffers(This,dwSize,dwAlignment,dwCount) ) + ( (This)->lpVtbl -> RequestBuffers(This,dwSize,dwAlignment,dwCount) ) #define IServerVirtualDeviceSet2_QueryAvailableBuffers(This,dwSize,dwAlignment,pCount) \ - ( (This)->lpVtbl -> QueryAvailableBuffers(This,dwSize,dwAlignment,pCount) ) + ( (This)->lpVtbl -> QueryAvailableBuffers(This,dwSize,dwAlignment,pCount) ) #define IServerVirtualDeviceSet2_ExecuteCompletionAgent(This) \ - ( (This)->lpVtbl -> ExecuteCompletionAgent(This) ) + ( (This)->lpVtbl -> ExecuteCompletionAgent(This) ) #define IServerVirtualDeviceSet2_OpenDevice(This,lpName,ppVirtualDevice) \ - ( (This)->lpVtbl -> OpenDevice(This,lpName,ppVirtualDevice) ) + ( (This)->lpVtbl -> OpenDevice(This,lpName,ppVirtualDevice) ) #define IServerVirtualDeviceSet2_AllocateBuffer(This,ppBuffer,dwSize,dwAlignment) \ - ( (This)->lpVtbl -> AllocateBuffer(This,ppBuffer,dwSize,dwAlignment) ) + ( (This)->lpVtbl -> AllocateBuffer(This,ppBuffer,dwSize,dwAlignment) ) #define IServerVirtualDeviceSet2_FreeBuffer(This,pBuffer,dwSize) \ - ( (This)->lpVtbl -> FreeBuffer(This,pBuffer,dwSize) ) + ( (This)->lpVtbl -> FreeBuffer(This,pBuffer,dwSize) ) #define IServerVirtualDeviceSet2_IsSharedBuffer(This,pBuffer) \ - ( (This)->lpVtbl -> IsSharedBuffer(This,pBuffer) ) + ( (This)->lpVtbl -> IsSharedBuffer(This,pBuffer) ) #define IServerVirtualDeviceSet2_SignalAbort(This) \ - ( (This)->lpVtbl -> SignalAbort(This) ) + ( (This)->lpVtbl -> SignalAbort(This) ) #define IServerVirtualDeviceSet2_Close(This) \ - ( (This)->lpVtbl -> Close(This) ) + ( (This)->lpVtbl -> Close(This) ) #endif /* COBJMACROS */ @@ -1360,7 +1360,7 @@ EXTERN_C const IID IID_IServerVirtualDeviceSet2; -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_Open_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_Open_Proxy( IServerVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpInstanceName, /* [in] */ LPCWSTR lpSetName); @@ -1373,7 +1373,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_Open_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_GetConfiguration_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_GetConfiguration_Proxy( IServerVirtualDeviceSet2 * This, /* [out] */ struct VDConfig *pCfg); @@ -1385,7 +1385,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_GetConfiguration_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_BeginConfiguration_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_BeginConfiguration_Proxy( IServerVirtualDeviceSet2 * This, /* [in] */ DWORD dwFeatures, /* [in] */ DWORD dwBlockSize, @@ -1401,7 +1401,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_BeginConfiguration_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_EndConfiguration_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_EndConfiguration_Proxy( IServerVirtualDeviceSet2 * This); @@ -1412,7 +1412,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_EndConfiguration_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_RequestBuffers_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_RequestBuffers_Proxy( IServerVirtualDeviceSet2 * This, /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment, @@ -1426,7 +1426,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_RequestBuffers_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_QueryAvailableBuffers_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_QueryAvailableBuffers_Proxy( IServerVirtualDeviceSet2 * This, /* [in] */ DWORD dwSize, /* [in] */ DWORD dwAlignment, @@ -1440,7 +1440,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_QueryAvailableBuffers_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_ExecuteCompletionAgent_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_ExecuteCompletionAgent_Proxy( IServerVirtualDeviceSet2 * This); @@ -1451,7 +1451,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_ExecuteCompletionAgent_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_OpenDevice_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_OpenDevice_Proxy( IServerVirtualDeviceSet2 * This, /* [in] */ LPCWSTR lpName, /* [out] */ IServerVirtualDevice **ppVirtualDevice); @@ -1464,7 +1464,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_OpenDevice_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_AllocateBuffer_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_AllocateBuffer_Proxy( IServerVirtualDeviceSet2 * This, /* [out] */ BYTE **ppBuffer, /* [in] */ DWORD dwSize, @@ -1478,7 +1478,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_AllocateBuffer_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_FreeBuffer_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_FreeBuffer_Proxy( IServerVirtualDeviceSet2 * This, /* [in] */ BYTE *pBuffer, /* [in] */ DWORD dwSize); @@ -1491,7 +1491,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_FreeBuffer_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_IsSharedBuffer_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_IsSharedBuffer_Proxy( IServerVirtualDeviceSet2 * This, /* [in] */ BYTE *pBuffer); @@ -1503,7 +1503,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_IsSharedBuffer_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_SignalAbort_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_SignalAbort_Proxy( IServerVirtualDeviceSet2 * This); @@ -1514,7 +1514,7 @@ void __RPC_STUB IServerVirtualDeviceSet2_SignalAbort_Stub( DWORD *_pdwStubPhase); -HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_Close_Proxy( +HRESULT STDMETHODCALLTYPE IServerVirtualDeviceSet2_Close_Proxy( IServerVirtualDeviceSet2 * This); @@ -1529,21 +1529,19 @@ void __RPC_STUB IServerVirtualDeviceSet2_Close_Stub( #endif /* __IServerVirtualDeviceSet2_INTERFACE_DEFINED__ */ -/* interface __MIDL_itf_vdi_0000_0006 */ -/* [local] */ +/* interface __MIDL_itf_vdi_0014 */ +/* [local] */ const IID CLSID_WINFS_ClientVirtualDeviceSet = {0x50b99b13, 0x7b84, 0x44d3, {0x9c, 0x98, 0x26, 0x52, 0xbf, 0x14, 0x4d, 0x96}}; const IID CLSID_WINFS_ServerVirtualDeviceSet = {0x92e6b26b, 0x57da, 0x47ed, {0x81, 0x53, 0xdf, 0xf1, 0x87, 0xa7, 0x6d, 0xde}}; -const IID CLSID_WIDVDI_ClientVirtualDeviceSet = {0xa9a3fe12, 0x61c7, 0x496e, { 0xaa, 0xbf, 0xb8, 0x3e, 0x32, 0x87, 0xab, 0x82 }}; -const IID CLSID_WIDVDI_ServerVirtualDeviceSet = {0xa6f16b19, 0x40, 0x4947, { 0x8d, 0x3f, 0x52, 0xde, 0x12, 0x9b, 0xb6, 0x15 }}; #define CLSID_MSSQL_ClientVirtualDeviceSet IID_IClientVirtualDeviceSet #define CLSID_MSSQL_ServerVirtualDeviceSet IID_IServerVirtualDeviceSet #pragma pack(pop, _vdi_h_) -extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_0006_v0_0_c_ifspec; -extern RPC_IF_HANDLE __MIDL_itf_vdi_0000_0006_v0_0_s_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_vdi_0014_v0_0_c_ifspec; +extern RPC_IF_HANDLE __MIDL_itf_vdi_0014_v0_0_s_ifspec; /* Additional Prototypes for ALL interfaces */ diff --git a/samples/features/sqlvdi/vdierror.h b/samples/features/sqlvdi/include/vdierror.h similarity index 100% rename from samples/features/sqlvdi/vdierror.h rename to samples/features/sqlvdi/include/vdierror.h diff --git a/samples/features/sqlvdi/vdiguid.h b/samples/features/sqlvdi/include/vdiguid.h similarity index 83% rename from samples/features/sqlvdi/vdiguid.h rename to samples/features/sqlvdi/include/vdiguid.h index 0a034566..986f3590 100644 --- a/samples/features/sqlvdi/vdiguid.h +++ b/samples/features/sqlvdi/include/vdiguid.h @@ -1,11 +1,22 @@ + +/* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ + /* link this file in with the server and any clients */ -/* File created by MIDL compiler version 7.00.0408 */ + /* File created by MIDL compiler version 7.00.0408 */ /* at Tue Sep 28 18:18:04 2004 */ - +/* Compiler settings for vdi.idl: + Oicf, W1, Zp8, env=Win32 (32b run) + protocol : dce , ms_ext, c_ext, robust + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: + __declspec(uuid()), __declspec(selectany), __declspec(novtable) + DECLSPEC_UUID(), MIDL_INTERFACE() +*/ +//@@MIDL_FILE_HEADING( ) #if !defined(_M_IA64) && !defined(_M_AMD64) @@ -15,7 +26,7 @@ #ifdef __cplusplus extern "C"{ -#endif +#endif #include @@ -99,8 +110,8 @@ MIDL_DEFINE_GUID(IID, IID_IServerVirtualDeviceSet2,0xAECBD0D6,0x24C6,0x11d3,0x85 /* Compiler settings for vdi.idl: Oicf, W1, Zp8, env=Win64 (32b run,appending) protocol : dce , ms_ext, c_ext, robust - error checks: allocation ref bounds_check enum stub_data - VC __declspec() decoration level: + error checks: allocation ref bounds_check enum stub_data + VC __declspec() decoration level: __declspec(uuid()), __declspec(selectany), __declspec(novtable) DECLSPEC_UUID(), MIDL_INTERFACE() */ @@ -114,7 +125,7 @@ MIDL_DEFINE_GUID(IID, IID_IServerVirtualDeviceSet2,0xAECBD0D6,0x24C6,0x11d3,0x85 #ifdef __cplusplus extern "C"{ -#endif +#endif #include diff --git a/samples/features/sqlvdi/mprocess/mprocess.cpp b/samples/features/sqlvdi/mprocess/mprocess.cpp new file mode 100644 index 00000000..e2f17b1e --- /dev/null +++ b/samples/features/sqlvdi/mprocess/mprocess.cpp @@ -0,0 +1,648 @@ +/*********************************************************************** +Copyright (c) Microsoft Corporation +All Rights Reserved. +***********************************************************************/ +// This source code is an intended supplement to the Microsoft SQL +// Server online references and related electronic documentation. +// +// This sample is for instructional purposes only. +// Code contained herein is not intended to be used "as is" in real applications. +// +// mprocess.cpp : +// +// Test & demonstrate the use of multiple streams where each stream is +// handled by a secondary process. +// +// This is a sample program used to demonstrate the Virtual Device Interface +// feature of Microsoft SQL Server. +// +// The program will backup or restore the 'pubs' sample database. +// +// The program requires two command line parameters. +// 1) +// One of: +// b perform a backup +// r perform a restore +// +// s Act as a secondary client (used internally only) +// +// 2) +// If b or r is given, then a second parm gives the number of streams to use, +// (1-32). +// The secondary processes are invoked automatically, and the second parm is the +// stream id (0..31), the third parm the VDSName. +// + +#define _WIN32_DCOM + +#include // for 'CoInitialize()' +#include // for file operations +#include // for toupper () +#include + +#include "vdi.h" // interface declaration +#include "vdierror.h" // error constants +#include "vdiguid.h" // define the GUIDs + +void LogError ( + LPSTR location, // must always be provided + LPSTR description, // NULL is acceptable + DWORD errCode); // windows status code + +int performTransfer ( + IClientVirtualDevice* vd, + int backup, + int streamId); + +HANDLE execSQL (int doBackup, int nStreams); + +int +runSecondary (int streamId, IClientVirtualDeviceSet *vds); + +int +startSecondaries( + IClientVirtualDeviceSet *vds, + HANDLE hSQLProcess, // handle to process dealing with the SQL + int nStreams, // number of i/o streams + char* pgmName); // the name of this program + +// Using a GUID for the VDS Name is a good way to assure uniqueness. +// +WCHAR wVdsName [100]; + + +// +// main function +// +int main(int argc, char *argv[]) +{ + HRESULT hr; + IClientVirtualDeviceSet* vds = NULL ; + VDConfig config; + int badParm=TRUE; + int doBackup; + HANDLE hProcess; + int termCode = -1; + int nStreams=1; + int isSecondary = FALSE; + + // Check the input parm + // + if (argc >= 3) + { + sscanf (argv[2], "%d", &nStreams); + switch (toupper(argv[1][0])) + { + case 'B': + doBackup = TRUE; + badParm = FALSE; + break; + + case 'R': + doBackup = FALSE; + badParm = FALSE; + break; + + case 'S': + doBackup = FALSE; // we don't know or care + badParm = FALSE; + isSecondary = TRUE; + // nStreams is the streamid! + swprintf (wVdsName, L"%hs", argv[3]); + break; + } + } + + if (badParm) + { + printf ("useage: mprocess {B|R} \n" + "Demonstrate a multistream Backup or Restore using the Virtual Device Interface\n"); + exit (1); + } + + if (isSecondary) + { + printf("Secondary pid %d working on stream %d\n", GetCurrentProcessId (), nStreams); + } + else + { + // 1..32 streams. + // + if (nStreams < 1) + nStreams = 1; + else if (nStreams > 32) + nStreams = 32; + + printf ("Performing a %s using %d virtual device(s).\n", + (doBackup) ? "BACKUP" : "RESTORE", nStreams); + } + + // Initialize COM Library + // Note: _WIN32_DCOM must be defined during the compile. + // + hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); + + if (!SUCCEEDED (hr)) + { + printf ("Coinit fails: x%X\n", hr); + exit (1); + } + + + // Get an interface to the device set. + // Notice how we use a single IID for both the class and interface + // identifiers. + // + hr = CoCreateInstance ( + IID_IClientVirtualDeviceSet, + NULL, + CLSCTX_INPROC_SERVER, + IID_IClientVirtualDeviceSet, + (void**)&vds); + + if (!SUCCEEDED (hr)) + { + // This failure might happen if the DLL was not registered. + // + printf ("Could not create component: x%X\n", hr); + printf ("Check registration of SQLVDI.DLL and value of IID\n"); + goto exit; + } + + // Perform secondary processing, if this is a + // secondary process. + // + if (isSecondary) + { + termCode = runSecondary (nStreams, vds); + + goto exit; + } + + // The following logic is executed by the primary process. + // + + // Setup the VDI configuration we want to use. + // This program doesn't use any fancy features, so the + // only field to setup is the deviceCount. + // + // The server will treat the virtual device just like a pipe: + // I/O will be strictly sequential with only the basic commands. + // + memset (&config, 0, sizeof(config)); + + config.deviceCount = nStreams; + + // Create a GUID to use for a unique virtual device name + // + GUID vdsId; + CoCreateGuid (&vdsId); + StringFromGUID2 (vdsId, wVdsName, 49); + + // Create the virtual device set + // + hr = vds->Create (wVdsName, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Create fails: x%X", hr); + goto exit; + } + + // Send the SQL command, via isql in a subprocess. + // + printf("\nSending the SQL...\n"); + + hProcess = execSQL (doBackup, nStreams); + if (hProcess == NULL) + { + printf ("execSQL failed.\n"); + goto shutdown; + } + + + // Wait for the server to connect, completing the configuration. + // Notice that we wait a maximum of 15 seconds. + // + printf("\nWaiting for SQL to complete configuration...\n"); + + hr = vds->GetConfiguration (15000, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Getconfig fails: x%X\n", hr); + goto shutdown; + } + + // Handle the virtual devices in secondary processes. + // + printf ("\nSpawning secondary processes...\n"); + termCode = startSecondaries (vds, hProcess, nStreams, argv[0]); + +shutdown: + + // Close the set + // + vds->Close (); + + // COM reference counting: Release the interface. + // + vds->Release () ; + +exit: + + // Uninitialize COM Library + // + CoUninitialize () ; + + return termCode; +} + +// +// Execute a basic backup/restore, by starting 'osql' in a subprocess. +// +// Returns: +// NULL : failed to start isql +// else : process handle +// +HANDLE execSQL (int doBackup, int nStreams) +{ + char cmd[5000]; + char extend[100]; + PROCESS_INFORMATION pi; + STARTUPINFO si; + int ix; + + // Build the SQL, submitting it via 'isql' + // If you want to use Windows NT Authentication, please do not use the -U or -P options. + sprintf (cmd, + "osql -E -b -Q\"%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'", + (doBackup) ? "BACKUP" : "RESTORE", + (doBackup) ? "TO" : "FROM", + wVdsName); + + for (ix=1; ix= WAIT_OBJECT_0 && + waitStatus < WAIT_OBJECT_0+nActive) + { + // One of the children completed. + // Determine which one. + // + ix = waitStatus - WAIT_OBJECT_0; + + // Check its completion code + // + if (!GetExitCodeProcess (children[ix], &exitCode)) + { + LogError ("startSecondary", "GetExitCode", GetLastError ()); + goto errorExit; + } + + if (exitCode != 0) + { + printf ("A child exitted with code %d\n", exitCode); + goto errorExit; + } + + // It is good programming practice to close handles when + // finished with them. + // Since this sample simply terminates the process for error + // handling, we don't need to do it, as handles are automatically + // closed as part of process termination. + // + CloseHandle (children[ix]); + + // Remove the handle for this child + // + memmove (&children[ix], &children[ix+1], + sizeof (HANDLE) * (nActive-ix-1)); + + nActive--; + + } + else + { + printf("Unexpected wait code: %d\n", waitStatus); + goto errorExit; + } + + } while (nActive > 0); + + printf ("All children completed successfully\n"); + + return 0; + +errorExit: + // Handle all problems in a trivial fashion: + // SignalAbort() will cause all processes using the virtual device set + // to terminate processing. + // Thus, we don't bother waiting for any children to terminate. + // + vds->SignalAbort (); + return -1; + +} + +//------------------------------------------------------------------ +// Perform secondary client processing +// Return 0 if no errors detected, else nonzero. +// +int +runSecondary (int streamId, IClientVirtualDeviceSet *vds) +{ + HRESULT hr; + WCHAR devName[100]; + IClientVirtualDevice* vd; + VDConfig config; + int termCode; + + // Open the device + // + if (streamId == 0) + { + // The first device has the same name as the set. + // + wcscpy (devName, wVdsName); + } + else + { + // For this example, we've simply appended a number + // for additional devices. You are free to name them + // as you wish. + // + swprintf (devName, L"%ls%d", wVdsName, streamId); + } + + // Open the virtual device set in this secondary process. + // + hr = vds->OpenInSecondary (wVdsName); + if (!SUCCEEDED (hr)) + { + printf ("VD::Open(%ls) fails: x%X", devName, hr); + return -1; + } + + // Open the device assigned to this process. + // + hr = vds->OpenDevice (devName, &vd); + if (!SUCCEEDED (hr)) + { + printf ("OpenDevice fails on %ls: x%X", devName, hr); + return -1; + } + + // Grab the config to figure out data direction + // + hr = vds->GetConfiguration (INFINITE, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Getconfig fails: x%X\n", hr); + termCode = -1; + goto errExit; + } + + printf ("\nPerforming data transfer...\n"); + + termCode = performTransfer (vd, + (config.features&VDF_WriteMedia), streamId); + +errExit: + + // If errors were detected, force an abort. + // + if (termCode != 0) + { + vds->SignalAbort (); + } + + vds->Close (); + + return termCode; +} + + +// This routine reads commands from the server until a 'Close' status is received. +// It simply synchronously reads or writes a file on the root of the current drive. +// +// Returns 0, if no errors are detected, else non-zero. +// +int performTransfer ( + IClientVirtualDevice* vd, + int backup, + int streamId) +{ + FILE * fh; + char fname[80]; + VDC_Command * cmd; + DWORD completionCode; + DWORD bytesTransferred; + HRESULT hr; + int termCode = -1; + + sprintf (fname, "multi.%d.dmp", streamId); + + fh = fopen (fname, (backup)? "wb" : "rb"); + if (fh == NULL ) + { + printf ("Failed to open: %s\n", fname); + return -1; + } + + while (SUCCEEDED (hr=vd->GetCommand (INFINITE, &cmd))) + { + bytesTransferred = 0; + switch (cmd->commandCode) + { + case VDC_Read: + bytesTransferred = fread (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size) + completionCode = ERROR_SUCCESS; + else + // assume failure is eof + completionCode = ERROR_HANDLE_EOF; + + break; + + case VDC_Write: + bytesTransferred = fwrite (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size ) + { + completionCode = ERROR_SUCCESS; + } + else + // assume failure is disk full + completionCode = ERROR_DISK_FULL; + break; + + case VDC_Flush: + fflush (fh); + completionCode = ERROR_SUCCESS; + break; + + case VDC_ClearError: + completionCode = ERROR_SUCCESS; + break; + + default: + // If command is unknown... + completionCode = ERROR_NOT_SUPPORTED; + } + + + hr = vd->CompleteCommand (cmd, completionCode, bytesTransferred, 0); + if (!SUCCEEDED (hr)) + { + printf ("Completion Failed: x%X\n", hr); + break; + } + } + + if (hr != VD_E_CLOSE) + { + printf ("Unexpected termination: x%X\n", hr); + } + else + { + // As far as the data transfer is concerned, no + // errors occurred. The code which issues the SQL + // must determine if the backup/restore was + // really successful. + // + printf ("Successfully completed data transfer.\n"); + termCode = 0; + } + + fclose (fh); + + return termCode; +} + +//-------------------------------------------------------------------- +// +// A simple error logger. +// +void LogError ( + LPSTR location, // must always be provided + LPSTR description, // NULL is acceptable + DWORD errCode) // windows status code +{ + LPVOID lpMsgBuf; + + printf ( + "Error at %s: %s StatusCode: %X\n", + location, + (description==NULL)?"":description, + errCode); + + // Attempt to explain the code + // + if (errCode != 0 && FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, 0, NULL ) )// Process any inserts in lpMsgBuf. + { + printf ("Explanation: %s\n", lpMsgBuf); + LocalFree( lpMsgBuf ); + } +} + diff --git a/samples/features/sqlvdi/mprocess/mprocess.dsp b/samples/features/sqlvdi/mprocess/mprocess.dsp new file mode 100644 index 00000000..646cca91 --- /dev/null +++ b/samples/features/sqlvdi/mprocess/mprocess.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="mprocess" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=mprocess - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mprocess.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mprocess.mak" CFG="mprocess - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mprocess - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "mprocess - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mprocess - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "mprocess - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "mprocess - Win32 Release" +# Name "mprocess - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\mprocess.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/samples/features/sqlvdi/mprocess/mprocess.dsw b/samples/features/sqlvdi/mprocess/mprocess.dsw new file mode 100644 index 00000000..b9ae7ee9 --- /dev/null +++ b/samples/features/sqlvdi/mprocess/mprocess.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "mprocess"=.\mprocess.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/samples/features/sqlvdi/mthread/mthread.cpp b/samples/features/sqlvdi/mthread/mthread.cpp new file mode 100644 index 00000000..3430e8a2 --- /dev/null +++ b/samples/features/sqlvdi/mthread/mthread.cpp @@ -0,0 +1,600 @@ +/*********************************************************************** +Copyright (c) Microsoft Corporation +All Rights Reserved. +***********************************************************************/ +// This source code is an intended supplement to the Microsoft SQL +// Server online references and related electronic documentation. +// +// This sample is for instructional purposes only. +// Code contained herein is not intended to be used "as is" in real applications. +// +// mthread.cpp : +// +// Test & demonstrate the use of multiple streams from a single process. +// +// This is a sample program used to demonstrate the Virtual Device Interface +// feature of Microsoft SQL Server. +// +// The program will backup or restore the 'pubs' sample database. +// +// The program requires two command line parameters. +// 1) +// One of: +// b perform a backup +// r perform a restore +// +// 2) +// The number of streams to use, 1-32. +// + +#define _WIN32_DCOM + +#include // for 'CoInitialize()' +#include // for file operations +#include // for toupper () +#include // for C library-safe _beginthreadex,_endthreadex +#include + +#include "vdi.h" // interface declaration +#include "vdierror.h" // error constants +#include "vdiguid.h" // define the GUIDs + +void LogError ( + LPSTR location, // must always be provided + LPSTR description, // NULL is acceptable + DWORD errCode); // windows status code + +int performTransfer ( + IClientVirtualDevice* vd, + int backup, + int streamId); + +HANDLE execSQL (int doBackup, int nStreams); + +int +startSecondaries( + IClientVirtualDeviceSet *vds, + HANDLE hSQLProcess, // handle to process dealing with the SQL + int nStreams); // number of i/o streams + +unsigned __stdcall +runSecondary (void *parms); + +// Using a GUID for the VDS Name is a good way to assure uniqueness. +// +WCHAR wVdsName [50]; + +// +// main function +// +int main(int argc, char *argv[]) +{ + HRESULT hr; + IClientVirtualDeviceSet* vds = NULL ; + VDConfig config; + int badParm=TRUE; + int doBackup; + HANDLE hProcess; + int termCode = -1; + int nStreams=1; + + // Check the input parm + // + if (argc == 3) + { + sscanf (argv[2], "%d", &nStreams); + switch (toupper(argv[1][0])) + { + case 'B': + doBackup = TRUE; + badParm = FALSE; + break; + + case 'R': + doBackup = FALSE; + badParm = FALSE; + break; + } + } + + if (badParm) + { + printf ("useage: mprocess {B|R} \n" + "Demonstrate a multistream Backup or Restore using the Virtual Device Interface\n"); + exit (1); + } + + // 1..32 streams. + // + if (nStreams < 1) + nStreams = 1; + else if (nStreams > 32) + nStreams = 32; + + printf ("Performing a %s using %d virtual device(s).\n", + (doBackup) ? "BACKUP" : "RESTORE", nStreams); + + // Initialize COM Library + // Note: _WIN32_DCOM must be defined during the compile. + // + hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); + + if (!SUCCEEDED (hr)) + { + printf ("Coinit fails: x%X\n", hr); + exit (1); + } + + + // Get an interface to the device set. + // Notice how we use a single IID for both the class and interface + // identifiers. + // + hr = CoCreateInstance ( + IID_IClientVirtualDeviceSet, + NULL, + CLSCTX_INPROC_SERVER, + IID_IClientVirtualDeviceSet, + (void**)&vds); + + if (!SUCCEEDED (hr)) + { + // This failure might happen if the DLL was not registered. + // + printf ("Could not create component: x%X\n", hr); + printf ("Check registration of SQLVDI.DLL and value of IID\n"); + goto exit; + } + + // Create a GUID to use for a unique virtual device name + // + GUID vdsId; + CoCreateGuid (&vdsId); + StringFromGUID2 (vdsId, wVdsName, 49); + + // Setup the VDI configuration we want to use. + // This program doesn't use any fancy features, so the + // only field to setup is the deviceCount. + // + // The server will treat the virtual device just like a pipe: + // I/O will be strictly sequential with only the basic commands. + // + memset (&config, 0, sizeof(config)); + + config.deviceCount = nStreams; + + // Create the virtual device set + // + hr = vds->Create (wVdsName, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Create fails: x%X", hr); + goto exit; + } + + // Send the SQL command, via isql in a subprocess. + // + printf("\nSending the SQL...\n"); + + hProcess = execSQL (doBackup, nStreams); + if (hProcess == NULL) + { + printf ("execSQL failed.\n"); + goto shutdown; + } + + + // Wait for the server to connect, completing the configuration. + // Notice that we wait a maximum of 15 seconds. + // + printf("\nWaiting for SQL to complete configuration...\n"); + + hr = vds->GetConfiguration (15000, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Getconfig fails: x%X\n", hr); + goto shutdown; + } + + // Handle the virtual devices in secondary processes. + // + printf ("\nSpawning secondary threads..\n"); + termCode = startSecondaries (vds, hProcess, nStreams); + +shutdown: + + // Close the set + // + vds->Close (); + + // COM reference counting: Release the interface. + // + vds->Release () ; + +exit: + + // Uninitialize COM Library + // + CoUninitialize () ; + + return termCode; +} + +// +// Execute a basic backup/restore, by starting 'isql' in a subprocess. +// +// Returns: +// NULL : failed to start isql +// else : process handle +// +HANDLE execSQL (int doBackup, int nStreams) +{ + char cmd[5000]; + char extend[100]; + PROCESS_INFORMATION pi; + STARTUPINFO si; + int ix; + + sprintf (cmd, "osql -E -b -Q\"%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'", + (doBackup) ? "BACKUP" : "RESTORE", + (doBackup) ? "TO" : "FROM", + wVdsName); + + for (ix=1; ix= WAIT_OBJECT_0+nActive) + { + LogError ("startSecondary", "WaitForMultiple", GetLastError ()); + printf("Unexpected wait code: %d\n", waitStatus); + goto errorExit; + } + + // All of the children have completed. + // Get the completion code from 'isql' to check for sucess. + // + if (!GetExitCodeProcess (hSQLProcess, &exitCode)) + { + LogError ("startSecondary", "GetExitCode", GetLastError ()); + goto errorExit; + } + + if (exitCode != 0) + { + printf ("The SQL operation failed with code %d\n", exitCode); + goto errorExit; + } + + printf ("The SQL operation was sucessful.\n"); + + // Be sure to close handles when finished with them. + // + // Notice that in our trivial error handling here we + // don't bother closing them, since handles are + // automatically closed as part of process termination. + // + for (ix = 0; ix < nActive; ix++) + { + CloseHandle (children[ix]); + } + + return 0; + +errorExit: + // Handle all problems in a trivial fashion: + // SignalAbort() will cause all processes using the virtual device set + // to terminate processing. + // + vds->SignalAbort (); + + // However, since the threads are using the virtual device set allocated + // by the main thread, we can't let the main thread close the set before + // the threads are finished with it. There are two options: + // 1) exit the process immediately. + // 2) wait for the threads to terminate. + // + // Option 2 is "cleaner" but requires more code, so we just exit here: + // + ExitProcess ((unsigned)-1); + + return -1; // ExitProcess doesn't return; this avoids a compiler error. +} + +//------------------------------------------------------------------ +// Perform secondary client processing from within a thread. +// Exits with 0 if no errors detected, else nonzero. +// The caller must setup a THREAD_PARMS parameter block when +// spawning the thread. +// +unsigned __stdcall +runSecondary (void *parms) +{ + HRESULT hr; + WCHAR devName[100]; + IClientVirtualDevice* vd; + VDConfig config; + int termCode; + + // Fetch the input parms + // + int streamId = ((THREAD_PARMS*)parms)->streamId; + IClientVirtualDeviceSet * vds = ((THREAD_PARMS*)parms)->vds; + + // Build the name of the device assigned to this thread. + // + if (streamId == 0) + { + // The first device has the same name as the set. + // + wcscpy (devName, wVdsName); + } + else + { + // For this example, we've simply appended a number + // for additional devices. You are free to name them + // as you wish. + // + swprintf (devName, L"%s%d", wVdsName, streamId); + } + + // Open the device assigned to this thread. + // + hr = vds->OpenDevice (devName, &vd); + if (!SUCCEEDED (hr)) + { + printf ("OpenDevice fails on %ls: x%X", devName, hr); + termCode = -1; + goto errExit; + } + + // Grab the config to figure out data direction + // + hr = vds->GetConfiguration (INFINITE, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Getconfig fails: x%X\n", hr); + termCode = -1; + goto errExit; + } + + printf ("\nPerforming data transfer...\n"); + + termCode = performTransfer (vd, + (config.features&VDF_WriteMedia), streamId); + +errExit: + + // If errors were detected, force an abort. + // + if (termCode != 0) + { + vds->SignalAbort (); + } + + return ((unsigned)termCode); + +} + + + +// This routine reads commands from the server until a 'Close' status is received. +// It simply synchronously reads or writes a file on the root of the current drive. +// +// Returns 0, if no errors are detected, else non-zero. +// +int performTransfer ( + IClientVirtualDevice* vd, + int backup, + int streamId) +{ + FILE * fh; + char fname[80]; + VDC_Command * cmd; + DWORD completionCode; + DWORD bytesTransferred; + HRESULT hr; + int termCode = -1; + + sprintf (fname, "multi.%d.dmp", streamId); + + fh = fopen (fname, (backup)? "wb" : "rb"); + if (fh == NULL ) + { + printf ("Failed to open: %s\n", fname); + return -1; + } + + while (SUCCEEDED (hr=vd->GetCommand (INFINITE, &cmd))) + { + bytesTransferred = 0; + switch (cmd->commandCode) + { + case VDC_Read: + bytesTransferred = fread (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size) + completionCode = ERROR_SUCCESS; + else + // assume failure is eof + completionCode = ERROR_HANDLE_EOF; + + break; + + case VDC_Write: + bytesTransferred = fwrite (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size ) + { + completionCode = ERROR_SUCCESS; + } + else + // assume failure is disk full + completionCode = ERROR_DISK_FULL; + break; + + case VDC_Flush: + fflush (fh); + completionCode = ERROR_SUCCESS; + break; + + case VDC_ClearError: + completionCode = ERROR_SUCCESS; + break; + + default: + // If command is unknown... + completionCode = ERROR_NOT_SUPPORTED; + } + + + hr = vd->CompleteCommand (cmd, completionCode, bytesTransferred, 0); + if (!SUCCEEDED (hr)) + { + printf ("Completion Failed: x%X\n", hr); + break; + } + } + + if (hr != VD_E_CLOSE) + { + printf ("Unexpected termination: x%X\n", hr); + } + else + { + // As far as the data transfer is concerned, no + // errors occurred. The code which issues the SQL + // must determine if the backup/restore was + // really successful. + // + printf ("Successfully completed data transfer.\n"); + termCode = 0; + } + + fclose (fh); + + return termCode; +} + + +//-------------------------------------------------------------------- +// +// A simple error logger. +// +void LogError ( + LPSTR location, // must always be provided + LPSTR description, // NULL is acceptable + DWORD errCode) // windows status code +{ + LPVOID lpMsgBuf; + + printf ( + "Error at %s: %s StatusCode: %X\n", + location, + (description==NULL)?"":description, + errCode); + + // Attempt to explain the code + // + if (errCode != 0 && FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + errCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, 0, NULL ) )// Process any inserts in lpMsgBuf. + { + printf ("Explanation: %s\n", lpMsgBuf); + LocalFree( lpMsgBuf ); + } +} + diff --git a/samples/features/sqlvdi/mthread/mthread.dsp b/samples/features/sqlvdi/mthread/mthread.dsp new file mode 100644 index 00000000..9b852163 --- /dev/null +++ b/samples/features/sqlvdi/mthread/mthread.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="mthread" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=mthread - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mthread.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mthread.mak" CFG="mthread - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mthread - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "mthread - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mthread - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "mthread - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "mthread - Win32 Release" +# Name "mthread - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\mthread.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/samples/features/sqlvdi/mthread/mthread.dsw b/samples/features/sqlvdi/mthread/mthread.dsw new file mode 100644 index 00000000..052e314d --- /dev/null +++ b/samples/features/sqlvdi/mthread/mthread.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "mthread"=.\mthread.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/samples/features/sqlvdi/osimple/osimple.cpp b/samples/features/sqlvdi/osimple/osimple.cpp new file mode 100644 index 00000000..118d080e --- /dev/null +++ b/samples/features/sqlvdi/osimple/osimple.cpp @@ -0,0 +1,659 @@ +/*********************************************************************** +Copyright (c) Microsoft Corporation +All Rights Reserved. +***********************************************************************/ +// This source code is an intended supplement to the Microsoft SQL +// Server online references and related electronic documentation. +// +// This sample is for instructional purposes only. +// Code contained herein is not intended to be used "as is" in real applications. +// +// osimple.cpp +// +// This sample extends the "simple.cpp" sample to use an ODBC connection. +// This is intended only as an introduction to ODBC; not as a comprehensive tutorial. +// +// This is a sample program used to demonstrate the Virtual Device Interface +// feature of Microsoft SQL Server together with an ODBC connection. +// +// The program will backup or restore the 'pubs' sample database from +// the default instance of sql server. +// +// The program accepts a single command line parameter. +// One of: +// b perform a backup +// r perform a restore +// + + +// To gain access to free threaded COM, you'll need to define _WIN32_DCOM +// before the system headers, either in the source (as in this example), +// or when invoking the compiler (by using /D "_WIN32_DCOM") +// +// This sample uses Windows NT Authentication, other than mixed mode security, +// to establish connections. If you want to use mixed mode security, please +// set Trusted_Connection to no in the SQLDriverConnect command. +// Make necessary change to the server name in the SQLDriverConnect command. + +#define _WIN32_DCOM + +#include // for 'CoInitialize()' +#include // for file operations +#include // for toupper () +#include // for C library-safe _beginthreadex,_endthreadex + +#include "vdi.h" // interface declaration +#include "vdierror.h" // error constants + +#include "vdiguid.h" // define the interface identifiers. + // IMPORTANT: vdiguid.h can only be included in one source file. + // + +#include +#include "sql.h" +#include "sqlext.h" +#include "odbcss.h" + +void performTransfer ( + IClientVirtualDevice* vd, + int backup ); + +HANDLE execSQL (int doBackup); +int checkSQL (HANDLE); + +// Using a GUID for the VDS Name is a good way to assure uniqueness. +// +WCHAR wVdsName [50]; + +//------------------------------------------------------------ +// +// Mainline +// +int main (int argc, char *argv[]) +{ + HRESULT hr; + IClientVirtualDeviceSet2* vds = NULL ; + IClientVirtualDevice* vd=NULL; + + VDConfig config; + int badParm=TRUE; + int doBackup; + HANDLE hThread = NULL; + + // Check the input parm + // + if (argc == 2) + { + if (toupper(argv[1][0]) == 'B') + { + doBackup = TRUE; + badParm = FALSE; + } + else if (toupper(argv[1][0]) == 'R') + { + doBackup = FALSE; + badParm = FALSE; + } + } + + if (badParm) + { + printf ("useage: osimple {B|R}\n" + "Demonstrate a Backup or Restore using the Virtual Device Interface & ODBC\n"); + exit (1); + } + + printf ("Performing a %s using a virtual device.\n", + (doBackup) ? "BACKUP" : "RESTORE"); + + // Initialize COM Library + // Note: _WIN32_DCOM must be defined during the compile. + // + hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); + + if (!SUCCEEDED (hr)) + { + printf ("Coinit fails: x%X\n", hr); + exit (1); + } + + // Get an interface to the device set. + // Notice how we use a single IID for both the class and interface + // identifiers. + // + hr = CoCreateInstance ( + CLSID_MSSQL_ClientVirtualDeviceSet, + NULL, + CLSCTX_INPROC_SERVER, + IID_IClientVirtualDeviceSet2, + (void**)&vds); + + if (!SUCCEEDED (hr)) + { + // This failure might happen if the DLL was not registered, + // or if the application is using the wrong interface id (IID). + // + printf ("Could not create component: x%X\n", hr); + printf ("Check registration of SQLVDI.DLL and value of IID\n"); + goto exit; + } + + // Setup the VDI configuration we want to use. + // This program doesn't use any fancy features, so the + // only field to setup is the deviceCount. + // + // The server will treat the virtual device just like a pipe: + // I/O will be strictly sequential with only the basic commands. + // + memset (&config, 0, sizeof(config)); + config.deviceCount = 1; + + // Create a GUID to use for a unique virtual device name + // + GUID vdsId; + CoCreateGuid (&vdsId); + StringFromGUID2 (vdsId, wVdsName, 49); + + // Create the virtual device set + // + hr = vds->CreateEx (NULL, wVdsName, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Create fails: x%X", hr); + goto exit; + } + + // Send the SQL command, by starting a thread to handle the ODBC + // + printf("\nSending the SQL...\n"); + + hThread = execSQL (doBackup); + if (hThread == NULL) + { + printf ("execSQL failed.\n"); + goto shutdown; + } + + // Wait for the server to connect, completing the configuration. + // + printf ("\nWaiting for SQLServer to respond...\n"); + + while (!SUCCEEDED (hr=vds->GetConfiguration (1000, &config))) + { + if (hr == VD_E_TIMEOUT) + { + // Check on the SQL thread + // + DWORD rc = WaitForSingleObject (hThread, 1000); + if (rc == WAIT_OBJECT_0) + { + printf ("SQL command failed before VD transfer\n"); + goto shutdown; + } + if (rc == WAIT_TIMEOUT) + { + continue; + } + printf ("Check on SQL failed: %d\n", rc); + goto shutdown; + } + + printf ("VDS::Getconfig fails: x%X\n", hr); + goto shutdown; + } + + // Open the single device in the set. + // + hr = vds->OpenDevice (wVdsName, &vd); + if (!SUCCEEDED(hr)) + { + printf ("VDS::OpenDevice fails: x%X\n", hr); + goto shutdown; + } + + printf ("\nPerforming data transfer...\n"); + + performTransfer (vd, doBackup); + + +shutdown: + + // Close the set + // + vds->Close (); + + // Obtain the SQL completion information + // + if (hThread != NULL) + { + if (checkSQL (hThread)) + printf("\nThe SQL command executed successfully.\n"); + else + printf("\nThe SQL command failed.\n"); + + CloseHandle (hThread); + } + + // COM reference counting: Release the interface. + // + vds->Release () ; + +exit: + // Uninitialize COM Library + // + CoUninitialize () ; + + return 0 ; +} + +//--------------------------------------------------------------------------- +// ODBC Message processing routine. +// This is SQLServer specific, to show native message IDs, sev, state. +// +// The routine will watch for message 3014 in order to detect +// a successful backup/restore operation. This is useful for +// operations like RESTORE which can sometimes recover from +// errors (error messages will be followed by the 3014 success message). +// +void ProcessMessages ( + SQLSMALLINT handle_type, // ODBC handle type + SQLHANDLE handle, // ODBC handle + int ConnInd, // TRUE if sucessful connection made + int* pBackupSuccess) // Set TRUE if a 3014 message is seen. +{ + RETCODE plm_retcode = SQL_SUCCESS; + UCHAR plm_szSqlState[SQL_SQLSTATE_SIZE + 1]; + UCHAR plm_szErrorMsg[SQL_MAX_MESSAGE_LENGTH + 1]; + SDWORD plm_pfNativeError = 0L; + SWORD plm_pcbErrorMsg = 0; + SQLSMALLINT plm_cRecNmbr = 1; + SDWORD plm_SS_MsgState = 0, plm_SS_Severity = 0; + SQLINTEGER plm_Rownumber = 0; + USHORT plm_SS_Line; + SQLSMALLINT plm_cbSS_Procname, plm_cbSS_Srvname; + SQLCHAR plm_SS_Procname[MAXNAME], plm_SS_Srvname[MAXNAME]; + + while (plm_retcode != SQL_NO_DATA_FOUND) + { + plm_retcode = SQLGetDiagRec(handle_type, handle, + plm_cRecNmbr, plm_szSqlState, &plm_pfNativeError, + plm_szErrorMsg, SQL_MAX_MESSAGE_LENGTH, &plm_pcbErrorMsg); + + // Note that if the application has not yet made a + // successful connection, the SQLGetDiagField + // information has not yet been cached by ODBC + // Driver Manager and these calls to SQLGetDiagField + // will fail. + // + if (plm_retcode != SQL_NO_DATA_FOUND) + { + if (ConnInd) + { + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_ROW_NUMBER, &plm_Rownumber, + SQL_IS_INTEGER, + NULL); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_LINE, &plm_SS_Line, + SQL_IS_INTEGER, + NULL); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_MSGSTATE, &plm_SS_MsgState, + SQL_IS_INTEGER, + NULL); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_SEVERITY, &plm_SS_Severity, + SQL_IS_INTEGER, + NULL); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_PROCNAME, &plm_SS_Procname, + sizeof(plm_SS_Procname), + &plm_cbSS_Procname); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_SRVNAME, &plm_SS_Srvname, + sizeof(plm_SS_Srvname), + &plm_cbSS_Srvname); + + printf ("Msg %d, SevLevel %d, State %d, SQLState %s\n", + plm_pfNativeError, + plm_SS_Severity, + plm_SS_MsgState, + plm_szSqlState); + } + + printf ("%s\n", plm_szErrorMsg); + + if (pBackupSuccess && plm_pfNativeError == 3014) + { + *pBackupSuccess = TRUE; + } + } + + plm_cRecNmbr++; //Increment to next diagnostic record. + } // End while. +} + + + +//------------------------------------------------------------------ +// The mainline of the ODBC thread. +// +// Returns TRUE if a successful backup/restore is performed. +// +unsigned __stdcall +SQLRoutine (void *parms) +{ + int doBackup = (int)parms; + + char sqlCommand [1024]; // way more space than we'll need. + int successDetected = FALSE; + + // ODBC handles + // + SQLHENV henv = NULL; + SQLHDBC hdbc = NULL; + SQLHSTMT hstmt = NULL; + + + sprintf (sqlCommand, "%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'", + (doBackup) ? "BACKUP" : "RESTORE", + (doBackup) ? "TO" : "FROM", + wVdsName); + + int sentSQL = FALSE; + int rc; + + #define MAX_CONN_OUT 1024 + SQLCHAR szOutConn[MAX_CONN_OUT]; + SQLSMALLINT cbOutConn; + + // Initialize the ODBC environment. + // + if (SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv) == SQL_ERROR) + goto exit; + + // This is an ODBC v3 application + // + SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, SQL_IS_INTEGER); + + // Allocate a connection handle + // + if (SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc) == SQL_ERROR) + { + printf ("AllocHandle on DBC failed."); + goto exit; + } + + // Connect to the server using Trusted connection. + // Trusted connection uses integrated NT security. + // If you want to use mixed-mode Authentication, please set Trusted_Connection to no. + rc = SQLDriverConnect( + hdbc, + NULL, // no diaglogs please + (SQLCHAR*) "DRIVER={SQL Server};Trusted_Connection=yes;SERVER=(local)", + SQL_NTS, + szOutConn, + MAX_CONN_OUT, + &cbOutConn, + SQL_DRIVER_NOPROMPT); + + if (rc == SQL_ERROR) + { + SQLCHAR szSqlState[20]; + SQLINTEGER ssErr; + SQLCHAR szErrorMsg [MAX_CONN_OUT]; + SQLSMALLINT cbErrorMsg; + + printf ("Connect fails\n"); + + rc = SQLError ( + henv, hdbc, SQL_NULL_HSTMT, + szSqlState, + &ssErr, + szErrorMsg, + MAX_CONN_OUT, + &cbErrorMsg); + + printf ("msg=%s\n", szErrorMsg); + + goto exit; + } + + // Get a statement handle + // + if (SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt) == SQL_ERROR) + { + printf ("Failed to get statement handle\n"); + + ProcessMessages (SQL_HANDLE_DBC, hdbc, TRUE, NULL); + goto exit; + } + + // Execute the SQL + // + printf ("Executing %s\n", sqlCommand); + + rc = SQLExecDirect (hstmt, (SQLCHAR*)sqlCommand, SQL_NTS); + + // Extract all the resulting messages + // + + SQLSMALLINT numResultCols; + while (1) + { + switch (rc) + { + case SQL_ERROR: + successDetected = FALSE; + ProcessMessages (SQL_HANDLE_STMT, hstmt, TRUE, &successDetected); + if (!successDetected) + { + printf ("Errors resulted in failure of the command\n"); + goto exit; + } + printf ("Errors were encountered but the command was able to recover and successfully complete.\n"); + break; + + case SQL_SUCCESS_WITH_INFO: + ProcessMessages (SQL_HANDLE_STMT, hstmt, TRUE, NULL); + // fall through + + case SQL_SUCCESS: + successDetected = TRUE; + + numResultCols = 0; + SQLNumResultCols (hstmt, &numResultCols); + if (numResultCols > 0) + { + printf ("A result set with %d columns was produced\n", + (int)numResultCols); + } + break; + + case SQL_NO_DATA: + // All results have been processed. We are done. + // + goto exit; + + case SQL_NEED_DATA: + case SQL_INVALID_HANDLE: + case SQL_STILL_EXECUTING: + default: + successDetected = FALSE; + printf ("Unexpected SQLExec result %d\n", rc); + goto exit; + } + rc = SQLMoreResults (hstmt); + } + +exit: + // Release the ODBC resources. + // + if (hstmt != NULL) + { + SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + hstmt = NULL; + } + + if (hdbc != NULL) + { + SQLDisconnect(hdbc); + SQLFreeHandle(SQL_HANDLE_DBC, hdbc); + hdbc = NULL; + } + + if (henv != NULL) + { + SQLFreeHandle(SQL_HANDLE_ENV, henv); + henv = NULL; + } + + return successDetected; +} + + +//------------------------------------------------------------ +// +// execSQL: Send the SQL to the server via ODBC. +// +// Return the thread handle (NULL on error). +// +HANDLE execSQL (int doBackup) +{ + unsigned int threadId; + HANDLE hThread; + + hThread = (HANDLE)_beginthreadex ( + NULL, 0, SQLRoutine, (void*)doBackup, 0, &threadId); + if (hThread == NULL) + { + printf ("Failed to create thread. errno is %d\n", errno); + } + return hThread; +} + +//------------------------------------------------------------ +// +// checkSQL: Wait for the T-SQL to complete, +// returns TRUE if statement successfully executed. +// +int checkSQL (HANDLE hThread) +{ + if (hThread == NULL) + return FALSE; + + DWORD rc = WaitForSingleObject (hThread, INFINITE); + if (rc != WAIT_OBJECT_0) + { + printf ("checkSQL failed: %d\n", rc); + return FALSE; + } + if (!GetExitCodeThread (hThread, &rc)) + { + printf ("failed to get exit code: %d\n", GetLastError ()); + return FALSE; + } + return rc == TRUE; +} + + + + +//---------------------------------------------------------------------------------- +// VDI data transfer handler. +// +// This routine reads commands from the server until a 'Close' status is received. +// It simply reads or writes a file 'superbak.dmp' in the current directory. +// +void performTransfer ( + IClientVirtualDevice* vd, + int backup ) +{ + FILE * fh; + char* fname = "superbak.dmp"; + VDC_Command * cmd; + DWORD completionCode; + DWORD bytesTransferred; + HRESULT hr; + + fh = fopen (fname, (backup)? "wb" : "rb"); + if (fh == NULL ) + { + printf ("Failed to open: %s\n", fname); + return; + } + + while (SUCCEEDED (hr=vd->GetCommand (INFINITE, &cmd))) + { + bytesTransferred = 0; + switch (cmd->commandCode) + { + case VDC_Read: + bytesTransferred = fread (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size) + completionCode = ERROR_SUCCESS; + else + // assume failure is eof + completionCode = ERROR_HANDLE_EOF; + break; + + case VDC_Write: + bytesTransferred = fwrite (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size ) + { + completionCode = ERROR_SUCCESS; + } + else + // assume failure is disk full + completionCode = ERROR_DISK_FULL; + break; + + case VDC_Flush: + fflush (fh); + completionCode = ERROR_SUCCESS; + break; + + case VDC_ClearError: + completionCode = ERROR_SUCCESS; + break; + + default: + // If command is unknown... + completionCode = ERROR_NOT_SUPPORTED; + } + + hr = vd->CompleteCommand (cmd, completionCode, bytesTransferred, 0); + if (!SUCCEEDED (hr)) + { + printf ("Completion Failed: x%X\n", hr); + break; + } + } + + if (hr != VD_E_CLOSE) + { + printf ("Unexpected termination: x%X\n", hr); + } + else + { + // As far as the data transfer is concerned, no + // errors occurred. The code which issues the SQL + // must determine if the backup/restore was + // really successful. + // + printf ("Successfully completed data transfer.\n"); + } + + fclose (fh); +} diff --git a/samples/features/sqlvdi/osimple/osimple.dsp b/samples/features/sqlvdi/osimple/osimple.dsp new file mode 100644 index 00000000..80794401 --- /dev/null +++ b/samples/features/sqlvdi/osimple/osimple.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="osimple" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=osimple - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "osimple.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "osimple.mak" CFG="osimple - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "osimple - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "osimple - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "osimple - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "osimple - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "osimple - Win32 Release" +# Name "osimple - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\osimple.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/samples/features/sqlvdi/osimple/osimple.dsw b/samples/features/sqlvdi/osimple/osimple.dsw new file mode 100644 index 00000000..52cd0ba3 --- /dev/null +++ b/samples/features/sqlvdi/osimple/osimple.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "osimple"=.\osimple.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/samples/features/sqlvdi/simple/simple.cpp b/samples/features/sqlvdi/simple/simple.cpp new file mode 100644 index 00000000..60e1bff4 --- /dev/null +++ b/samples/features/sqlvdi/simple/simple.cpp @@ -0,0 +1,348 @@ +/*********************************************************************** +Copyright (c) Microsoft Corporation +All Rights Reserved. +***********************************************************************/ +// This source code is an intended supplement to the Microsoft SQL +// Server online references and related electronic documentation. +// +// This sample is for instructional purposes only. +// Code contained herein is not intended to be used "as is" in real applications. +// +// simple.cpp +// +// This is a sample program used to demonstrate the Virtual Device Interface +// feature of Microsoft SQL Server. +// +// The program will backup or restore the 'pubs' sample database. +// +// The program accepts a single command line parameter. +// One of: +// b perform a backup +// r perform a restore +// + + +// To gain access to free threaded COM, you'll need to define _WIN32_DCOM +// before the system headers, either in the source (as in this example), +// or when invoking the compiler (by using /D "_WIN32_DCOM") +// +#define _WIN32_DCOM + +#include // for 'CoInitialize()' +#include // for file operations +#include // for toupper () +#include // for spawn () + +#include "vdi.h" // interface declaration +#include "vdierror.h" // error constants + +#include "vdiguid.h" // define the interface identifiers. + // IMPORTANT: vdiguid.h can only be included in one source file. + // + + +void performTransfer ( + IClientVirtualDevice* vd, + int backup ); + +int execSQL (int doBackup); + +// Using a GUID for the VDS Name is a good way to assure uniqueness. +// +WCHAR wVdsName [50]; + + +// +// main function +// +int main(int argc, char *argv[]) +{ + HRESULT hr; + IClientVirtualDeviceSet2* vds = NULL ; + IClientVirtualDevice* vd=NULL; + + VDConfig config; + int badParm=TRUE; + int doBackup; + int hProcess; + int termCode; + + // Check the input parm + // + if (argc == 2) + { + if (toupper(argv[1][0]) == 'B') + { + doBackup = TRUE; + badParm = FALSE; + } + else if (toupper(argv[1][0]) == 'R') + { + doBackup = FALSE; + badParm = FALSE; + } + } + + if (badParm) + { + printf ("useage: simple {B|R}\n" + "Demonstrate a Backup or Restore using the Virtual Device Interface\n"); + exit (1); + } + + // Initialize COM Library + // Note: _WIN32_DCOM must be defined during the compile. + // + hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); + + if (!SUCCEEDED (hr)) + { + printf ("Coinit fails: x%X\n", hr); + exit (1); + } + + // Get an interface to the device set. + // Changes from SQLServer v7.0: + // - we've introduced a symbol for the class ID. + // - We've added a new "multi-instance-aware" interface. + // + hr = CoCreateInstance ( + CLSID_MSSQL_ClientVirtualDeviceSet, + NULL, + CLSCTX_INPROC_SERVER, + IID_IClientVirtualDeviceSet2, + (void**)&vds); + + if (!SUCCEEDED (hr)) + { + // This failure might happen if the DLL was not registered, + // or if the application is using the wrong interface id (IID). + // + printf ("Could not create component: x%X\n", hr); + printf ("Check registration of SQLVDI.DLL and value of IID\n"); + goto exit; + } + + // Setup the VDI configuration we want to use. + // This program doesn't use any fancy features, so the + // only field to setup is the deviceCount. + // + // The server will treat the virtual device just like a pipe: + // I/O will be strictly sequential with only the basic commands. + // + memset (&config, 0, sizeof(config)); + config.deviceCount = 1; + + // Create a GUID to use for a unique virtual device name + // + GUID vdsId; + CoCreateGuid (&vdsId); + StringFromGUID2 (vdsId, wVdsName, 49); + + // Create the virtual device set + // for use by the default instance. + // Change the first parameter to identify a named instance. + // + hr = vds->CreateEx (NULL, wVdsName, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Create fails: x%X", hr); + goto exit; + } + + // Send the SQL command, by starting 'isql' in a subprocess. + // + printf("\nSending the SQL...\n"); + + hProcess = execSQL (doBackup); + if (hProcess == -1) + { + printf ("execSQL failed.\n"); + goto shutdown; + } + + // Wait for the server to connect, completing the configuration. + // + hr = vds->GetConfiguration (10000, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Getconfig fails: x%X\n", hr); + if (hr == VD_E_TIMEOUT) + { + printf ("Timed out. Was Microsoft SQLServer running?\n"); + } + goto shutdown; + } + + // Open the single device in the set. + // + hr = vds->OpenDevice (wVdsName, &vd); + if (!SUCCEEDED(hr)) + { + printf ("VDS::OpenDevice fails: x%X\n", hr); + goto shutdown; + } + + printf ("\nPerforming data transfer...\n"); + + performTransfer (vd, doBackup); + + +shutdown: + + // Close the set + // + vds->Close (); + + // Obtain the SQL completion information, by waiting for isql to exit. + // + if (hProcess == _cwait( &termCode, hProcess, NULL)) + { + if (termCode == 0) + printf("\nThe SQL command executed successfully.\n"); + else + printf("\nThe SQL command failed.\n"); + } + else + { + printf ("cwait failed: %d\n", errno); + } + + // COM reference counting: Release the interface. + // + // Rather than releasing it, the application has the + // option to 'Create' another set, reusing the interface + // that it currently has. Of course that applies to + // a real application, not this simple sample! + // + vds->Release () ; + +exit: + + // Uninitialize COM Library + // + CoUninitialize () ; + + return 0 ; +} + +// +// Execute a basic backup/restore, by spawning a process to execute 'isql'. +// +// Returns: +// -1 : failed to spawn +// else : a "process handle" +// +int execSQL (int doBackup) +{ + char sqlCommand [1024]; // plenty of space for our purpose + + sprintf (sqlCommand, "-Q\"%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'\"", + (doBackup) ? "BACKUP" : "RESTORE", + (doBackup) ? "TO" : "FROM", + wVdsName); + int rc; + + printf ("spawning osql to execute: %s\n", sqlCommand); + + // Spawn off the osql utility to execute the SQL. + // Notice the '-b' which causes an error to set a non-zero + // exit code on error. + // + rc = _spawnlp( _P_NOWAIT, "osql", "osql", "-E", "-b", + sqlCommand, NULL); + + if (rc == -1) + { + printf ("Spawn failed with error: %d\n", errno); + } + + return (rc); +} + +// This routine reads commands from the server until a 'Close' status is received. +// It simply reads or writes a file 'superbak.dmp' in the current directory. +// +void performTransfer ( + IClientVirtualDevice* vd, + int backup ) +{ + FILE * fh; + char* fname = "superbak.dmp"; + VDC_Command * cmd; + DWORD completionCode; + DWORD bytesTransferred; + HRESULT hr; + + fh = fopen (fname, (backup)? "wb" : "rb"); + if (fh == NULL ) + { + printf ("Failed to open: %s\n", fname); + return; + } + + while (SUCCEEDED (hr=vd->GetCommand (INFINITE, &cmd))) + { + bytesTransferred = 0; + switch (cmd->commandCode) + { + case VDC_Read: + bytesTransferred = fread (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size) + completionCode = ERROR_SUCCESS; + else + // assume failure is eof + completionCode = ERROR_HANDLE_EOF; + break; + + case VDC_Write: + bytesTransferred = fwrite (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size ) + { + completionCode = ERROR_SUCCESS; + } + else + // assume failure is disk full + completionCode = ERROR_DISK_FULL; + break; + + case VDC_Flush: + fflush (fh); + completionCode = ERROR_SUCCESS; + break; + + case VDC_ClearError: + completionCode = ERROR_SUCCESS; + break; + + default: + // If command is unknown... + completionCode = ERROR_NOT_SUPPORTED; + } + + hr = vd->CompleteCommand (cmd, completionCode, bytesTransferred, 0); + if (!SUCCEEDED (hr)) + { + printf ("Completion Failed: x%X\n", hr); + break; + } + } + + if (hr != VD_E_CLOSE) + { + printf ("Unexpected termination: x%X\n", hr); + } + else + { + // As far as the data transfer is concerned, no + // errors occurred. The code which issues the SQL + // must determine if the backup/restore was + // really successful. + // + printf ("Successfully completed data transfer.\n"); + } + + fclose (fh); +} + + diff --git a/samples/features/sqlvdi/simple/simple.dsp b/samples/features/sqlvdi/simple/simple.dsp new file mode 100644 index 00000000..d759c378 --- /dev/null +++ b/samples/features/sqlvdi/simple/simple.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="simple" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=simple - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "simple.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "simple.mak" CFG="simple - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "simple - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "simple - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "simple - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "simple - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "simple - Win32 Release" +# Name "simple - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\simple.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/samples/features/sqlvdi/simple/simple.dsw b/samples/features/sqlvdi/simple/simple.dsw new file mode 100644 index 00000000..f38a9abf --- /dev/null +++ b/samples/features/sqlvdi/simple/simple.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "simple"=.\simple.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/samples/features/sqlvdi/snapshot/snapshot.cpp b/samples/features/sqlvdi/snapshot/snapshot.cpp new file mode 100644 index 00000000..be8cf262 --- /dev/null +++ b/samples/features/sqlvdi/snapshot/snapshot.cpp @@ -0,0 +1,828 @@ +/*********************************************************************** +Copyright (c) Microsoft Corporation +All Rights Reserved. +***********************************************************************/ +// This source code is an intended supplement to the Microsoft SQL +// Server online references and related electronic documentation. +// +// This sample is for instructional purposes only. +// Code contained herein is not intended to be used "as is" in real applications. +// +// snapshot.cpp +// +// This sample extends the "osimple.cpp" sample to demonstrate BACKUP WITH SNAPSHOT. +// It is not fully functional. The ability to take/mount snapshots must be provided. +// +// This is a sample program used to demonstrate the Virtual Device Interface +// feature of Microsoft SQL Server together with an ODBC connection. +// +// The program will request backup or restore of a single database +// on some instance of sql server. +// +// The program accepts input: +// {b | r} [] +// b -> backup +// r -> restore +// + + +// To gain access to free threaded COM, you'll need to define _WIN32_DCOM +// before the system headers, either in the source (as in this example), +// or when invoking the compiler (by using /D "_WIN32_DCOM") +// +// This sample uses Windows NT Authentication, other than mixed mode security, +// to establish connections. If you want to use mixed mode security, please +// set Trusted_Connection to no in the SQLDriverConnect command. +// Make necessary change to the server name in the SQLDriverConnect command. +// +#define _WIN32_DCOM + +#include // for 'CoInitialize()' +#include // for file operations +#include // for toupper () +#include // for C library-safe _beginthreadex,_endthreadex + +#include "vdi.h" // interface declaration +#include "vdierror.h" // error constants + +#include "vdiguid.h" // define the interface identifiers. + // IMPORTANT: vdiguid.h can only be included in one source file. + // + +#include +#include "sql.h" +#include "sqlext.h" +#include "odbcss.h" + +void performTransfer ( + IClientVirtualDeviceSet2* vds, + IClientVirtualDevice* vd, + int backup ); + +HANDLE execSQL (int doBackup, char* pInstanceName, char* pDbName, WCHAR* pVdsName); +int checkSQL (HANDLE); + +BOOL +ynPrompt (char *str); + +//------------------------------------------------------------ +// +// Mainline +// +int __cdecl +main (int argc, char *argv[]) +{ + HRESULT hr; + IClientVirtualDeviceSet2* vds = NULL ; + IClientVirtualDevice* vd=NULL; + + VDConfig config; + int badParm=TRUE; + int doBackup; + HANDLE hThread = NULL; + char* pDbName = NULL; + char* pInstanceName = NULL; + + // Check the input parm + // + if (argc >= 3) + { + if (toupper(argv[1][0]) == 'B') + { + doBackup = TRUE; + badParm = FALSE; + } + else if (toupper(argv[1][0]) == 'R') + { + doBackup = FALSE; + badParm = FALSE; + } + + pDbName = argv[2]; + + if (argc == 4) + { + pInstanceName = argv[3]; + } + } + + if (badParm) + { + printf ("useage: snapshot {B|R} []\n" + "Demonstrate a Backup or Restore WITH SNAPSHOT\n"); + printf ("\n\n** NOTE **\n The ability to take or mount snapshots must be implemented\n" + "before this sample is truely functional.\n"); + exit (1); + } + + printf ("Performing a %s of %s on %s using a VIRTUAL_DEVICE.\n", + (doBackup) ? "BACKUP" : "RESTORE", + pDbName, + (pInstanceName) ? pInstanceName : "Default"); + + // Initialize COM Library + // Note: _WIN32_DCOM must be defined during the compile. + // + hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); + + if (!SUCCEEDED (hr)) + { + printf ("Coinit fails: x%X\n", hr); + exit (1); + } + + // Get an interface to the device set. + // Notice how we use a single IID for both the class and interface + // identifiers. + // + hr = CoCreateInstance ( + CLSID_MSSQL_ClientVirtualDeviceSet, + NULL, + CLSCTX_INPROC_SERVER, + IID_IClientVirtualDeviceSet2, + (void**)&vds); + + if (!SUCCEEDED (hr)) + { + // This failure might happen if the DLL was not registered, + // or if the application is using the wrong interface id (IID). + // + printf ("Could not create component: x%X\n", hr); + printf ("Check registration of SQLVDI.DLL and value of IID\n"); + goto exit; + } + + // Setup the VDI configuration we want to use. + // This program doesn't use any fancy features, so the + // only field to setup is the deviceCount. + // + // The server will treat the virtual device just like a pipe: + // I/O will be strictly sequential with only the basic commands. + // + memset (&config, 0, sizeof(config)); + config.deviceCount = 1; + config.features = VDF_SnapshotPrepare; + + // Create a GUID to use for a unique virtual device name + // + GUID vdsId; + WCHAR wVdsName [50]; + CoCreateGuid (&vdsId); + StringFromGUID2 (vdsId, wVdsName, 49); + + // Create the virtual device set + // Notice that we only support unicode interfaces + // + WCHAR wInstanceName [128]; + int rc = 0; + if (pInstanceName) + { + rc = MultiByteToWideChar (CP_ACP, 0, + pInstanceName, strlen (pInstanceName), + wInstanceName, 127); + } + wInstanceName [rc] = 0; + + hr = vds->CreateEx (wInstanceName, wVdsName, &config); + if (!SUCCEEDED (hr)) + { + printf ("VDS::Create fails: x%X", hr); + goto exit; + } + + // Send the SQL command, by starting a thread to handle the ODBC + // + printf("\nSending the SQL...\n"); + + hThread = execSQL (doBackup, pInstanceName, pDbName, wVdsName); + if (hThread == NULL) + { + printf ("execSQL failed.\n"); + goto shutdown; + } + + // Wait for the server to connect, completing the configuration. + // + printf ("\nWaiting for SQLServer to respond...\n"); + + while (!SUCCEEDED (hr=vds->GetConfiguration (1000, &config))) + { + if (hr == VD_E_TIMEOUT) + { + // Check on the SQL thread + // + DWORD rc = WaitForSingleObject (hThread, 1000); + if (rc == WAIT_OBJECT_0) + { + printf ("SQL command failed before VD transfer\n"); + goto shutdown; + } + if (rc == WAIT_TIMEOUT) + { + continue; + } + printf ("Check on SQL failed: %d\n", rc); + goto shutdown; + } + + printf ("VDS::Getconfig fails: x%X\n", hr); + goto shutdown; + } + + // Open the single device in the set. + // + hr = vds->OpenDevice (wVdsName, &vd); + if (!SUCCEEDED(hr)) + { + printf ("VDS::OpenDevice fails: x%X\n", hr); + goto shutdown; + } + + printf ("\nPerforming data transfer...\n"); + + performTransfer (vds, vd, doBackup); + + +shutdown: + + // Close the set + // + vds->Close (); + + // Obtain the SQL completion information + // + if (hThread != NULL) + { + if (checkSQL (hThread)) + printf("\nThe SQL command executed successfully.\n"); + else + printf("\nThe SQL command failed.\n"); + + CloseHandle (hThread); + } + + // COM reference counting: Release the interface. + // + vds->Release () ; + +exit: + // Uninitialize COM Library + // + CoUninitialize () ; + + return 0 ; +} + +//--------------------------------------------------------------------------- +// ODBC Message processing routine. +// This is SQLServer specific, to show native message IDs, sev, state. +// +// The routine will watch for message 3014 in order to detect +// a successful backup/restore operation. This is useful for +// operations like RESTORE which can sometimes recover from +// errors (error messages will be followed by the 3014 success message). +// +void ProcessMessages ( + SQLSMALLINT handle_type, // ODBC handle type + SQLHANDLE handle, // ODBC handle + int ConnInd, // TRUE if sucessful connection made + int* pBackupSuccess) // Set TRUE if a 3014 message is seen. +{ + RETCODE plm_retcode = SQL_SUCCESS; + UCHAR plm_szSqlState[SQL_SQLSTATE_SIZE + 1]; + UCHAR plm_szErrorMsg[SQL_MAX_MESSAGE_LENGTH + 1]; + SDWORD plm_pfNativeError = 0L; + SWORD plm_pcbErrorMsg = 0; + SQLSMALLINT plm_cRecNmbr = 1; + SDWORD plm_SS_MsgState = 0, plm_SS_Severity = 0; + SQLINTEGER plm_Rownumber = 0; + USHORT plm_SS_Line; + SQLSMALLINT plm_cbSS_Procname, plm_cbSS_Srvname; + SQLCHAR plm_SS_Procname[MAXNAME], plm_SS_Srvname[MAXNAME]; + + while (plm_retcode != SQL_NO_DATA_FOUND) + { + plm_retcode = SQLGetDiagRec(handle_type, handle, + plm_cRecNmbr, plm_szSqlState, &plm_pfNativeError, + plm_szErrorMsg, SQL_MAX_MESSAGE_LENGTH, &plm_pcbErrorMsg); + + // Note that if the application has not yet made a + // successful connection, the SQLGetDiagField + // information has not yet been cached by ODBC + // Driver Manager and these calls to SQLGetDiagField + // will fail. + // + if (plm_retcode != SQL_NO_DATA_FOUND) + { + if (ConnInd) + { + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_ROW_NUMBER, &plm_Rownumber, + SQL_IS_INTEGER, + NULL); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_LINE, &plm_SS_Line, + SQL_IS_INTEGER, + NULL); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_MSGSTATE, &plm_SS_MsgState, + SQL_IS_INTEGER, + NULL); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_SEVERITY, &plm_SS_Severity, + SQL_IS_INTEGER, + NULL); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_PROCNAME, &plm_SS_Procname, + sizeof(plm_SS_Procname), + &plm_cbSS_Procname); + + plm_retcode = SQLGetDiagField( + handle_type, handle, plm_cRecNmbr, + SQL_DIAG_SS_SRVNAME, &plm_SS_Srvname, + sizeof(plm_SS_Srvname), + &plm_cbSS_Srvname); + + printf ("Msg %d, SevLevel %d, State %d, SQLState %s\n", + plm_pfNativeError, + plm_SS_Severity, + plm_SS_MsgState, + plm_szSqlState); + } + + printf ("%s\n", plm_szErrorMsg); + + if (pBackupSuccess && plm_pfNativeError == 3014) + { + *pBackupSuccess = TRUE; + } + } + + plm_cRecNmbr++; //Increment to next diagnostic record. + } // End while. +} + + + +//------------------------------------------------------------------ +// The mainline of the ODBC thread. +// +// Returns TRUE if a successful backup/restore is performed. +// +struct PARMS +{ + int doBackup; + char* pInstanceName; + char* pDbName; + WCHAR* pVdsName; +}; + +unsigned __stdcall +SQLRoutine (void* input) +{ + PARMS* parms = (PARMS*)input; + + SQLCHAR* pSQLText; // the command being executed. + int successDetected = FALSE; + + // ODBC handles + // + SQLHENV henv = NULL; + SQLHDBC hdbc = NULL; + SQLHSTMT hstmt = NULL; + + char sqlCommand [1024]; + + int sentSQL = FALSE; + int rc; + + #define MAX_CONN_OUT 1024 + SQLCHAR szOutConn[MAX_CONN_OUT]; + SQLSMALLINT cbOutConn; + + // Convert the VDSNAME for use by the non-unicode interfaces we're using here. + // + char aVdsName [50]; + int aSize; + aSize = WideCharToMultiByte ( + CP_ACP, 0, + parms->pVdsName, + -1, // null terminated, so calculate + aVdsName, 49, + NULL, NULL ); // don't worry about fancy conversions + + + // Generate the command to execute + // + sprintf (sqlCommand, "%s DATABASE [%s] %s VIRTUAL_DEVICE='%s' WITH SNAPSHOT", + parms->doBackup ? "BACKUP" : "RESTORE", + parms->pDbName, + parms->doBackup ? "TO" : "FROM", + aVdsName); + + // Initialize the ODBC environment. + // + if (SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv) == SQL_ERROR) + goto exit; + + // This is an ODBC v3 application + // + SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, SQL_IS_INTEGER); + + // Allocate a connection handle + // + if (SQLAllocHandle (SQL_HANDLE_DBC, henv, &hdbc) == SQL_ERROR) + { + printf ("AllocHandle on DBC failed."); + goto exit; + } + + char connectString [200]; + strcpy (connectString, "DRIVER={SQL Server};Trusted_Connection=yes;SERVER=."); + if (parms->pInstanceName) + { + sprintf (connectString+strlen(connectString), "\\%s", parms->pInstanceName); + } + + printf ("\n\nConnecting with: %s\n", connectString); + + // Connect to the server using Trusted connection. + // Trusted connection uses integrated NT security. + // If you want to use mixed-mode Authentication, please set Trusted_Connection to no. + rc = SQLDriverConnect( + hdbc, + NULL, // no diaglogs please + (SQLCHAR*) connectString, + SQL_NTS, + szOutConn, + MAX_CONN_OUT, + &cbOutConn, + SQL_DRIVER_NOPROMPT); + + if (rc == SQL_ERROR) + { + SQLCHAR szSqlState[20]; + SQLINTEGER ssErr; + SQLCHAR szErrorMsg [MAX_CONN_OUT]; + SQLSMALLINT cbErrorMsg; + + printf ("Connect fails\n"); + + rc = SQLError ( + henv, hdbc, SQL_NULL_HSTMT, + szSqlState, + &ssErr, + szErrorMsg, + MAX_CONN_OUT, + &cbErrorMsg); + + printf ("msg=%s\n", szErrorMsg); + + goto exit; + } + + // Get a statement handle + // + if (SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt) == SQL_ERROR) + { + printf ("Failed to get statement handle\n"); + + ProcessMessages (SQL_HANDLE_DBC, hdbc, TRUE, NULL); + goto exit; + } + + // Execute the SQL + // + printf ("\n\nExecuting SQL: %s\n", sqlCommand); + + pSQLText = (SQLCHAR*)sqlCommand; + + rc = SQLExecDirect (hstmt, pSQLText, SQL_NTS); + + // Extract all the resulting messages + // + + SQLSMALLINT numResultCols; + while (1) + { + switch (rc) + { + case SQL_ERROR: + successDetected = FALSE; + ProcessMessages (SQL_HANDLE_STMT, hstmt, TRUE, &successDetected); + if (!successDetected) + { + printf ("Errors resulted in failure of the command\n"); + goto exit; + } + printf ("Errors were encountered but the command was able to recover and successfully complete.\n"); + break; + + case SQL_SUCCESS_WITH_INFO: + ProcessMessages (SQL_HANDLE_STMT, hstmt, TRUE, NULL); + // fall through + + case SQL_SUCCESS: + successDetected = TRUE; + + numResultCols = 0; + SQLNumResultCols (hstmt, &numResultCols); + if (numResultCols > 0) + { + printf ("A result set with %d columns was produced\n", + (int)numResultCols); + } + break; + + case SQL_NO_DATA: + // All results have been processed. We are done. + // + goto exit; + + case SQL_NEED_DATA: + case SQL_INVALID_HANDLE: + case SQL_STILL_EXECUTING: + default: + successDetected = FALSE; + printf ("Unexpected SQLExec result %d\n", rc); + goto exit; + } + rc = SQLMoreResults (hstmt); + } + +exit: + // Release the ODBC resources. + // + if (hstmt != NULL) + { + SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + hstmt = NULL; + } + + if (hdbc != NULL) + { + SQLDisconnect(hdbc); + SQLFreeHandle(SQL_HANDLE_DBC, hdbc); + hdbc = NULL; + } + + if (henv != NULL) + { + SQLFreeHandle(SQL_HANDLE_ENV, henv); + henv = NULL; + } + + return successDetected; +} + + +//------------------------------------------------------------ +// +// execSQL: Send the SQL to the server via ODBC. +// +// Return the thread handle (NULL on error). +// +HANDLE execSQL (int doBackup, char* pInstanceName, char* pDbName, WCHAR* pVDName) +{ + unsigned int threadId; + HANDLE hThread; + static PARMS parms; // yucky, but only a single command is used.... + + parms.doBackup = doBackup; + parms.pDbName = pDbName; + parms.pInstanceName = pInstanceName; + parms.pVdsName = pVDName; + + hThread = (HANDLE)_beginthreadex ( + NULL, 0, SQLRoutine, (void*)&parms, 0, &threadId); + if (hThread == NULL) + { + printf ("Failed to create thread. errno is %d\n", errno); + } + return hThread; +} + +//------------------------------------------------------------ +// +// checkSQL: Wait for the T-SQL to complete, +// returns TRUE if statement successfully executed. +// +int checkSQL (HANDLE hThread) +{ + if (hThread == NULL) + return FALSE; + + DWORD rc = WaitForSingleObject (hThread, INFINITE); + if (rc != WAIT_OBJECT_0) + { + printf ("checkSQL failed: %d\n", rc); + return FALSE; + } + if (!GetExitCodeThread (hThread, &rc)) + { + printf ("failed to get exit code: %d\n", GetLastError ()); + return FALSE; + } + return rc == TRUE; +} + + +//---------------------------------------------------------------------------------- +// Ask the user a "yes/no" question. +// Return TRUE if he answers "yes" +// +BOOL +ynPrompt (char *str) +{ + char line[256]; + + printf ("\n\n%s", str); + line [0] = 0; + gets (line); + printf ("\n\n"); + return (line [0] == 'y' || line [0] == 'Y'); +} + +//---------------------------------------------------------------------------------- +// VDI data transfer handler. +// +// This routine reads commands from the server until a 'Close' status is received. +// It simply reads or writes a file 'superbak.dmp' in the current directory. +// +void performTransfer ( + IClientVirtualDeviceSet2* iVds, + IClientVirtualDevice* vd, + int backup ) +{ + FILE * fh; + char* fname = "snapshot.dmp"; + VDC_Command * cmd; + DWORD completionCode; + DWORD bytesTransferred; + HRESULT hr; + + fh = fopen (fname, (backup)? "wb" : "rb"); + if (fh == NULL ) + { + printf ("Failed to open: %s\n", fname); + return; + } + + while (SUCCEEDED (hr=vd->GetCommand (INFINITE, &cmd))) + { + bytesTransferred = 0; + switch (cmd->commandCode) + { + case VDC_Read: + bytesTransferred = fread (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size) + completionCode = ERROR_SUCCESS; + else + // assume failure is eof + completionCode = ERROR_HANDLE_EOF; + break; + + case VDC_Write: + bytesTransferred = fwrite (cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size ) + { + completionCode = ERROR_SUCCESS; + } + else + // assume failure is disk full + completionCode = ERROR_DISK_FULL; + break; + + case VDC_Flush: + fflush (fh); + completionCode = ERROR_SUCCESS; + break; + + case VDC_ClearError: + completionCode = ERROR_SUCCESS; + break; + + case VDC_PrepareToFreeze: + printf ("\n*** SQL Server is prepared to freeze the database now ***\n"); + printf ("At this point the application can perform any final coordination activities.\n"); + + while (!ynPrompt ("Are you ready to freeze the database?")) + { + if (ynPrompt ("Do you want to abort?")) + { + iVds->SignalAbort (); + return; + } + } + // Acknowledging this command results in a freeze of database writes. + // The server will then issue VDC_Write commands to record metadata + // about the frozen state. + // Then the VDC_Snapshot is issued. + // + completionCode = ERROR_SUCCESS; + break; + + case VDC_Snapshot: + // At this point the metadata is complete, so the + // output stream can be closed. Thus it is possible + // to include the metadata with the data of the snapshot. + // + fclose (fh); + fh = NULL; + + printf ("\n*** Make the snapshot now ***\n"); + + while (!ynPrompt ("Did you complete the snapshot?")) + { + if (ynPrompt ("Do you want to abort?")) + { + iVds->SignalAbort (); + return; + } + } + + // For clarity, we "unroll" the loop logic + // in the following block of code so you can + // easily see the sequence of operations. + // + + // Tell SQLServer that the snapshot is done. + // + completionCode = ERROR_SUCCESS; + hr = vd->CompleteCommand (cmd, completionCode, bytesTransferred, 0); + if (!SUCCEEDED (hr)) + { + printf ("Completion Failed: x%X\n", hr); + return; + } + + // The only valid command will be a "close" request. + // + hr = vd->GetCommand (INFINITE, &cmd); + if (hr != VD_E_CLOSE) + { + printf ("Unexpected snapshot termination: x%X\n", hr); + } + else + { + printf ("SQLServer is aware that the snapshot is successful.\n"); + } + return; + + case VDC_MountSnapshot: + printf ("\n*** Mount the snapshot now ***\n"); + + while (!ynPrompt ("Did you complete the snapshot?")) + { + if (ynPrompt ("Do you want to abort?")) + { + iVds->SignalAbort (); + return; + } + } + completionCode = ERROR_SUCCESS; + break; + + default: + // If command is unknown... + completionCode = ERROR_NOT_SUPPORTED; + } + + hr = vd->CompleteCommand (cmd, completionCode, bytesTransferred, 0); + if (!SUCCEEDED (hr)) + { + printf ("Completion Failed: x%X\n", hr); + break; + } + } + + if (hr != VD_E_CLOSE) + { + printf ("Unexpected termination: x%X\n", hr); + } + else + { + // As far as the data transfer is concerned, no + // errors occurred. The code which issues the SQL + // must determine if the backup/restore was + // really successful. + // + printf ("Successfully completed data transfer.\n"); + } + + if (fh != NULL) + { + fclose (fh); + } +} + + diff --git a/samples/features/sqlvdi/snapshot/snapshot.dsp b/samples/features/sqlvdi/snapshot/snapshot.dsp new file mode 100644 index 00000000..55f9a285 --- /dev/null +++ b/samples/features/sqlvdi/snapshot/snapshot.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="snapshot" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=snapshot - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "snapshot.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "snapshot.mak" CFG="snapshot - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "snapshot - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "snapshot - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "snapshot - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "snapshot - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "snapshot - Win32 Release" +# Name "snapshot - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\snapshot.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/samples/features/sqlvdi/snapshot/snapshot.dsw b/samples/features/sqlvdi/snapshot/snapshot.dsw new file mode 100644 index 00000000..10da226d --- /dev/null +++ b/samples/features/sqlvdi/snapshot/snapshot.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "snapshot"=.\snapshot.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### +