diff --git a/samples/features/sqlvdi/README.md b/samples/features/sqlvdi/README.md index 11fbcf1f..9736b6cc 100644 --- a/samples/features/sqlvdi/README.md +++ b/samples/features/sqlvdi/README.md @@ -1,11 +1,6 @@ # SQLVDI This folder contains the latest files and samples required to build a SQL Server VDI based backup/restore application. -### Files available -1. vdi.h -2. vdierror.h -3. vdiguid.h - A new **VDC_Complete** command was added to SQLVDI that indicates SQL Server has completed sending data to the VDI client. Therefore, the VDI client will be able to finish the backup before it sends response to SQL Server. More details about this improvement in the SQLVDI protocol can be found in [KB3188454: Enhance VDI Protocol with VDC_Complete command in SQL Server] (https://support.microsoft.com/en-us/kb/3188454) diff --git a/samples/features/sqlvdi/mprocess/mprocess.cpp b/samples/features/sqlvdi/mprocess/mprocess.cpp index e2f17b1e..1b311aa5 100644 --- a/samples/features/sqlvdi/mprocess/mprocess.cpp +++ b/samples/features/sqlvdi/mprocess/mprocess.cpp @@ -44,216 +44,220 @@ All Rights Reserved. #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 +void LogError( + const char* location, // must always be provided + const char* description, // NULL is acceptable + DWORD errCode); // windows status code -int performTransfer ( - IClientVirtualDevice* vd, - int backup, - int streamId); +int performTransfer( + IClientVirtualDevice* vd, + int backup, + int streamId); -HANDLE execSQL (int doBackup, int nStreams); +HANDLE execSQL(bool doBackup, int nStreams); -int -runSecondary (int streamId, IClientVirtualDeviceSet *vds); +int runSecondary(int streamId, IClientVirtualDeviceSet2* 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 +int startSecondaries( + IClientVirtualDeviceSet2* 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]; - +WCHAR wVdsName[100]; // // main function // -int main(int argc, char *argv[]) +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; + HRESULT hr; + IClientVirtualDeviceSet2* vds = nullptr; + VDConfig config; + bool badParm = true; + bool doBackup; + HANDLE hProcess; + int termCode = -1; + int nStreams = 1; + bool 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; + // Check the input parm + // + if (argc >= 3) + { + sscanf_s(argv[2], "%d", &nStreams); - 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; - } - } + switch (toupper(argv[1][0])) + { + case 'B': + doBackup = true; + 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); - } + case 'R': + doBackup = false; + badParm = false; + break; - 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; + case 'S': + doBackup = false; // we don't know or care + badParm = false; + isSecondary = true; - printf ("Performing a %s using %d virtual device(s).\n", - (doBackup) ? "BACKUP" : "RESTORE", nStreams); - } + // nStreams is the streamid! + swprintf_s(wVdsName, L"%hs", argv[3]); + break; + } + } - // Initialize COM Library - // Note: _WIN32_DCOM must be defined during the compile. - // - hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); + if (badParm) + { + printf("usage: mprocess {B|R} \n" + "Demonstrate a multistream Backup or Restore using the Virtual Device Interface\n"); + exit(1); + } - if (!SUCCEEDED (hr)) - { - printf ("Coinit fails: x%X\n", hr); - 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(nullptr, COINIT_MULTITHREADED); + + if (FAILED(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); + // 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, + nullptr, + 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; - } + if (FAILED(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); + // Perform secondary processing, if this is a + // secondary process. + // + if (isSecondary) + { + termCode = runSecondary(nStreams, vds); - goto exit; - } + goto exit; + } - // The following logic is executed by the primary process. - // + // 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)); + // 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; + config.deviceCount = nStreams; // Create a GUID to use for a unique virtual device name // GUID vdsId; - CoCreateGuid (&vdsId); - StringFromGUID2 (vdsId, wVdsName, 49); + 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; - } + // Create the virtual device set + // for use by the default instance. + // + // To use a named instance, change the + // first parameter in CreateEx to your instance's name. + // + hr = vds->CreateEx(nullptr, wVdsName, &config); + if (FAILED(hr)) + { + printf("VDS::Create fails: x%X", hr); + goto exit; + } - // Send the SQL command, via isql in a subprocess. - // - printf("\nSending the SQL...\n"); + // 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; - } + hProcess = execSQL(doBackup, nStreams); + if (hProcess == nullptr) + { + 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"); + // 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; - } + hr = vds->GetConfiguration(15000, &config); + if (FAILED(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]); - // 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 (); + // Close the set + // + vds->Close(); - // COM reference counting: Release the interface. - // - vds->Release () ; + // COM reference counting: Release the interface. + // + vds->Release(); exit: - // Uninitialize COM Library - // - CoUninitialize () ; + // Uninitialize COM Library + // + CoUninitialize(); - return termCode; + return termCode; } // @@ -263,50 +267,54 @@ exit: // NULL : failed to start isql // else : process handle // -HANDLE execSQL (int doBackup, int nStreams) +HANDLE execSQL(bool doBackup, int nStreams) { - char cmd[5000]; - char extend[100]; - PROCESS_INFORMATION pi; - STARTUPINFO si; - int ix; + WCHAR cmd[5000]; + WCHAR 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", + // Build the SQL, submitting it via 'isql' + // If you want to use Windows NT Authentication, please do not use the -U or -P options. + // + // To use a named instance, change "-S ." to "-S .\\instance_name" + // + swprintf_s(cmd, L"osql -S . -E -b -Q\"%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'", + (doBackup) ? L"BACKUP" : L"RESTORE", + (doBackup) ? L"TO" : L"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; + // Wait for all to finish. + // Max wait is one minute for this tiny test. + // + printf("All children are now running.\n" + "Waiting for their completion...\n"); - // Check its completion code - // - if (!GetExitCodeProcess (children[ix], &exitCode)) - { - LogError ("startSecondary", "GetExitCode", GetLastError ()); - goto errorExit; - } + // Notice how this differs from the threaded model in mthread.cpp. + // In the multiprocess model, the primary client (running this code) + // is responsible for detecting abnormal termination of the + // secondary clients. + // A simple "wait-for-all" approach may wait indefinitely if only + // one of the secondaries was to abnormally terminate. + // + do + { + // Wait for any completion + // + waitStatus = WaitForMultipleObjects(nActive, children, + FALSE, INFINITE); - if (exitCode != 0) - { - printf ("A child exitted with code %d\n", exitCode); - goto errorExit; - } + if (waitStatus >= WAIT_OBJECT_0 && + waitStatus < WAIT_OBJECT_0 + nActive) + { + // One of the children completed. + // Determine which one. + // + ix = waitStatus - WAIT_OBJECT_0; - // 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]); + // Check its completion code + // + if (!GetExitCodeProcess(children[ix], &exitCode)) + { + LogError("startSecondary", "GetExitCode", GetLastError()); + goto errorExit; + } - // Remove the handle for this child - // - memmove (&children[ix], &children[ix+1], - sizeof (HANDLE) * (nActive-ix-1)); + if (exitCode != 0) + { + printf("A child exitted with code %d\n", exitCode); + goto errorExit; + } - nActive--; + // 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]); - } - else - { - printf("Unexpected wait code: %d\n", waitStatus); - goto errorExit; - } + // Remove the handle for this child + // + memmove(&children[ix], &children[ix + 1], + sizeof(HANDLE) * (nActive - ix - 1)); - } while (nActive > 0); + nActive--; - printf ("All children completed successfully\n"); + } + else + { + printf("Unexpected wait code: %d\n", waitStatus); + goto errorExit; + } - return 0; + } 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; + // 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; } @@ -444,77 +455,79 @@ errorExit: // Perform secondary client processing // Return 0 if no errors detected, else nonzero. // -int -runSecondary (int streamId, IClientVirtualDeviceSet *vds) +int runSecondary(int streamId, IClientVirtualDeviceSet2* vds) { - HRESULT hr; - WCHAR devName[100]; - IClientVirtualDevice* vd; - VDConfig config; - int termCode; + 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 device + // + if (streamId == 0) + { + // The first device has the same name as the set. + // + wcscpy_s(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_s(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 virtual device set in this secondary process. + // + // To use a named instance, change the + // first parameter in OpenInSecondaryEx to your instance's name. + // + hr = vds->OpenInSecondaryEx(nullptr, wVdsName); + if (FAILED(hr)) + { + wprintf(L"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; - } + // Open the device assigned to this process. + // + hr = vds->OpenDevice(devName, &vd); + if (FAILED(hr)) + { + wprintf(L"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; - } + // Grab the config to figure out data direction + // + hr = vds->GetConfiguration(INFINITE, &config); + if (FAILED(hr)) + { + wprintf(L"VDS::Getconfig fails: x%X\n", hr); + termCode = -1; + goto errExit; + } - printf ("\nPerforming data transfer...\n"); - - termCode = performTransfer (vd, - (config.features&VDF_WriteMedia), streamId); + 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 (); - } + // If errors were detected, force an abort. + // + if (termCode != 0) + { + vds->SignalAbort(); + } - vds->Close (); + vds->Close(); - return termCode; + return termCode; } @@ -523,126 +536,126 @@ errExit: // // Returns 0, if no errors are detected, else non-zero. // -int performTransfer ( - IClientVirtualDevice* vd, - int backup, - int streamId) +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; + FILE* fh; + char fname[80]; + VDC_Command* cmd; + DWORD completionCode; + DWORD bytesTransferred; + HRESULT hr; + int termCode = -1; - sprintf (fname, "multi.%d.dmp", streamId); + sprintf_s(fname, "multi.%d.dmp", streamId); - fh = fopen (fname, (backup)? "wb" : "rb"); - if (fh == NULL ) - { - printf ("Failed to open: %s\n", fname); - return -1; - } + errno_t error = fopen_s(&fh, fname, (backup) ? "wb" : "rb"); + if (error != 0) + { + 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; + 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; + 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_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_Flush: + fflush(fh); + completionCode = ERROR_SUCCESS; + break; - default: - // If command is unknown... - completionCode = ERROR_NOT_SUPPORTED; - } + 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; - } - } + hr = vd->CompleteCommand(cmd, completionCode, bytesTransferred, 0); + if (FAILED(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; - } + 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); + fclose(fh); - return termCode; + return termCode; } //-------------------------------------------------------------------- // // A simple error logger. // -void LogError ( - LPSTR location, // must always be provided - LPSTR description, // NULL is acceptable - DWORD errCode) // windows status code +void LogError( + const char* location, // must always be provided + const char* description, // NULL is acceptable + DWORD errCode) // windows status code { - LPVOID lpMsgBuf; + LPWSTR lpMsgBuf; - printf ( - "Error at %s: %s StatusCode: %X\n", - location, - (description==NULL)?"":description, - errCode); + printf( + "Error at %s: %s StatusCode: %X\n", + location, + (description == nullptr) ? "" : 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 ); - } + // Attempt to explain the code + // + if (errCode != 0 && FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + errCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + reinterpret_cast(&lpMsgBuf), 0, nullptr))// Process any inserts in lpMsgBuf. + { + printf("Explanation: %ls\n", lpMsgBuf); + LocalFree(lpMsgBuf); + } } diff --git a/samples/features/sqlvdi/mprocess/mprocess.dsp b/samples/features/sqlvdi/mprocess/mprocess.dsp deleted file mode 100644 index 646cca91..00000000 --- a/samples/features/sqlvdi/mprocess/mprocess.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# 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 deleted file mode 100644 index b9ae7ee9..00000000 --- a/samples/features/sqlvdi/mprocess/mprocess.dsw +++ /dev/null @@ -1,29 +0,0 @@ -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/mprocess/mprocess.vcxproj b/samples/features/sqlvdi/mprocess/mprocess.vcxproj new file mode 100644 index 00000000..cb17bce2 --- /dev/null +++ b/samples/features/sqlvdi/mprocess/mprocess.vcxproj @@ -0,0 +1,141 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {fe97585b-08bd-4837-a5ba-5c960e591f29} + mprocess + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\include + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/features/sqlvdi/mprocess/mprocess.vcxproj.filters b/samples/features/sqlvdi/mprocess/mprocess.vcxproj.filters new file mode 100644 index 00000000..6284fbca --- /dev/null +++ b/samples/features/sqlvdi/mprocess/mprocess.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/samples/features/sqlvdi/mthread/mthread.cpp b/samples/features/sqlvdi/mthread/mthread.cpp index 3430e8a2..b9e1fd63 100644 --- a/samples/features/sqlvdi/mthread/mthread.cpp +++ b/samples/features/sqlvdi/mthread/mthread.cpp @@ -39,185 +39,188 @@ All Rights Reserved. #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 +void LogError( + const char* location, // must always be provided + const char* description, // NULL is acceptable + DWORD errCode); // windows status code -int performTransfer ( - IClientVirtualDevice* vd, - int backup, - int streamId); +int performTransfer( + IClientVirtualDevice* vd, + int backup, + int streamId); -HANDLE execSQL (int doBackup, int nStreams); +HANDLE execSQL(bool doBackup, int nStreams); -int -startSecondaries( - IClientVirtualDeviceSet *vds, - HANDLE hSQLProcess, // handle to process dealing with the SQL - int nStreams); // number of i/o streams +int startSecondaries( + IClientVirtualDeviceSet2* vds, + HANDLE hSQLProcess, // handle to process dealing with the SQL + int nStreams); // number of i/o streams unsigned __stdcall -runSecondary (void *parms); +runSecondary(void* parms); // Using a GUID for the VDS Name is a good way to assure uniqueness. // -WCHAR wVdsName [50]; +WCHAR wVdsName[50]; // // main function // -int main(int argc, char *argv[]) +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; + HRESULT hr; + IClientVirtualDeviceSet2* vds = nullptr; + VDConfig config; + bool badParm = true; + bool 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; - } - } + // Check the input parm + // + if (argc == 3) + { + sscanf_s(argv[2], "%d", &nStreams); - if (badParm) - { - printf ("useage: mprocess {B|R} \n" - "Demonstrate a multistream Backup or Restore using the Virtual Device Interface\n"); - exit (1); - } + switch (toupper(argv[1][0])) + { + case 'B': + doBackup = true; + badParm = false; + break; - // 1..32 streams. - // - if (nStreams < 1) - nStreams = 1; - else if (nStreams > 32) - nStreams = 32; + case 'R': + doBackup = false; + badParm = false; + break; + } + } - printf ("Performing a %s using %d virtual device(s).\n", - (doBackup) ? "BACKUP" : "RESTORE", nStreams); + if (badParm) + { + printf("usage: mthread {B|R} \n" + "Demonstrate a multistream 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); + // 1..32 streams. + // + if (nStreams < 1) + nStreams = 1; + else if (nStreams > 32) + nStreams = 32; - if (!SUCCEEDED (hr)) - { - printf ("Coinit fails: x%X\n", hr); - exit (1); - } + 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(nullptr, COINIT_MULTITHREADED); + + if (FAILED(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); + // 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, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IClientVirtualDeviceSet2, + (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; - } + if (FAILED(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; + } + + // 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); + 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)); + // Create the virtual device set + // for use by the default instance. + // + // To use a named instance, change the + // first parameter in CreateEx to your instance's name. + // + hr = vds->CreateEx(nullptr, wVdsName, &config); + if (FAILED(hr)) + { + printf("VDS::Create fails: x%X", hr); + goto exit; + } - config.deviceCount = nStreams; + // Send the SQL command, via isql in a subprocess. + // + printf("\nSending the SQL...\n"); - // 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; - } + hProcess = execSQL(doBackup, nStreams); + if (hProcess == nullptr) + { + 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"); + // 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; - } + hr = vds->GetConfiguration(15000, &config); + if (FAILED(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); - // Handle the virtual devices in secondary processes. - // - printf ("\nSpawning secondary threads..\n"); - termCode = startSecondaries (vds, hProcess, nStreams); - shutdown: - // Close the set - // - vds->Close (); + // Close the set + // + vds->Close(); - // COM reference counting: Release the interface. - // - vds->Release () ; + // COM reference counting: Release the interface. + // + vds->Release(); exit: - // Uninitialize COM Library - // - CoUninitialize () ; + // Uninitialize COM Library + // + CoUninitialize(); - return termCode; + return termCode; } // @@ -227,47 +230,50 @@ exit: // NULL : failed to start isql // else : process handle // -HANDLE execSQL (int doBackup, int nStreams) +HANDLE execSQL(bool doBackup, int nStreams) { - char cmd[5000]; - char extend[100]; - PROCESS_INFORMATION pi; - STARTUPINFO si; - int ix; + WCHAR cmd[5000]; + WCHAR 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", + // To use a named instance, change "-S ." to "-S .\\instance_name" + swprintf_s(cmd, L"osql -S . -E -b -Q\"%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'", + (doBackup) ? L"BACKUP" : L"RESTORE", + (doBackup) ? L"TO" : L"FROM", wVdsName); - - for (ix=1; ix= WAIT_OBJECT_0+nActive) - { - LogError ("startSecondary", "WaitForMultiple", GetLastError ()); - printf("Unexpected wait code: %d\n", waitStatus); - goto errorExit; - } + // Wait for all to finish. + // Max wait is one minute for this tiny test. + // + printf("All children are now running.\n" + "Waiting for their completion...\n"); - // 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; - } + waitStatus = WaitForMultipleObjects(nActive, children, + true, 60000); - if (exitCode != 0) - { - printf ("The SQL operation failed with code %d\n", exitCode); - goto errorExit; - } + if (waitStatus < WAIT_OBJECT_0 || + waitStatus >= WAIT_OBJECT_0 + nActive) + { + LogError("startSecondary", "WaitForMultiple", GetLastError()); + printf("Unexpected wait code: %d\n", waitStatus); + goto errorExit; + } - printf ("The SQL operation was sucessful.\n"); + // 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; + } - // 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]); - } + if (exitCode != 0) + { + printf("The SQL operation failed with code %d\n", exitCode); + goto errorExit; + } - return 0; + 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 (); + // 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); + // 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. + return -1; // ExitProcess doesn't return; this avoids a compiler error. } //------------------------------------------------------------------ @@ -399,71 +407,71 @@ errorExit: // spawning the thread. // unsigned __stdcall -runSecondary (void *parms) +runSecondary(void* parms) { - HRESULT hr; - WCHAR devName[100]; - IClientVirtualDevice* vd; - VDConfig config; - int termCode; + 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; + // 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); - } + // Build the name of the device assigned to this thread. + // + if (streamId == 0) + { + // The first device has the same name as the set. + // + wcscpy_s(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_s(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; - } + // Open the device assigned to this thread. + // + hr = vds->OpenDevice(devName, &vd); + if (FAILED(hr)) + { + wprintf(L"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; - } + // Grab the config to figure out data direction + // + hr = vds->GetConfiguration(INFINITE, &config); + if (FAILED(hr)) + { + wprintf(L"VDS::Getconfig fails: x%X\n", hr); + termCode = -1; + goto errExit; + } - printf ("\nPerforming data transfer...\n"); - - termCode = performTransfer (vd, - (config.features&VDF_WriteMedia), streamId); + 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 (); - } + // If errors were detected, force an abort. + // + if (termCode != 0) + { + vds->SignalAbort(); + } - return ((unsigned)termCode); + return ((unsigned)termCode); } @@ -474,95 +482,95 @@ errExit: // // Returns 0, if no errors are detected, else non-zero. // -int performTransfer ( - IClientVirtualDevice* vd, - int backup, - int streamId) +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; + FILE* fh; + char fname[80]; + VDC_Command* cmd; + DWORD completionCode; + DWORD bytesTransferred; + HRESULT hr; + int termCode = -1; - sprintf (fname, "multi.%d.dmp", streamId); + sprintf_s(fname, "multi.%d.dmp", streamId); - fh = fopen (fname, (backup)? "wb" : "rb"); - if (fh == NULL ) - { - printf ("Failed to open: %s\n", fname); - return -1; - } + errno_t error = fopen_s(&fh, fname, (backup) ? "wb" : "rb"); + if (error != 0) + { + 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; + 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; + 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_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_Flush: + fflush(fh); + completionCode = ERROR_SUCCESS; + break; - default: - // If command is unknown... - completionCode = ERROR_NOT_SUPPORTED; - } + 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; - } - } + hr = vd->CompleteCommand(cmd, completionCode, bytesTransferred, 0); + if (FAILED(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; - } + 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); + fclose(fh); - return termCode; + return termCode; } @@ -570,31 +578,31 @@ int performTransfer ( // // A simple error logger. // -void LogError ( - LPSTR location, // must always be provided - LPSTR description, // NULL is acceptable - DWORD errCode) // windows status code +void LogError( + const char* location, // must always be provided + const char* description, // NULL is acceptable + DWORD errCode) // windows status code { - LPVOID lpMsgBuf; + LPWSTR lpMsgBuf = nullptr; - printf ( - "Error at %s: %s StatusCode: %X\n", - location, - (description==NULL)?"":description, - errCode); + printf( + "Error at %s: %s StatusCode: %X\n", + location, + (description == nullptr) ? "" : 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 ); - } + // Attempt to explain the code + // + if (errCode != 0 && FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + errCode, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + reinterpret_cast(&lpMsgBuf), 0, nullptr)) // Process any inserts in lpMsgBuf. + { + printf("Explanation: %ls\n", lpMsgBuf); + LocalFree(lpMsgBuf); + } } diff --git a/samples/features/sqlvdi/mthread/mthread.dsp b/samples/features/sqlvdi/mthread/mthread.dsp deleted file mode 100644 index 9b852163..00000000 --- a/samples/features/sqlvdi/mthread/mthread.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# 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 deleted file mode 100644 index 052e314d..00000000 --- a/samples/features/sqlvdi/mthread/mthread.dsw +++ /dev/null @@ -1,29 +0,0 @@ -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/mthread/mthread.vcxproj b/samples/features/sqlvdi/mthread/mthread.vcxproj new file mode 100644 index 00000000..82b3c0c2 --- /dev/null +++ b/samples/features/sqlvdi/mthread/mthread.vcxproj @@ -0,0 +1,141 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {f4600084-90ad-42b9-9809-ade6e1c06423} + mthread + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\include + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/features/sqlvdi/mthread/mthread.vcxproj.filters b/samples/features/sqlvdi/mthread/mthread.vcxproj.filters new file mode 100644 index 00000000..606cc8a8 --- /dev/null +++ b/samples/features/sqlvdi/mthread/mthread.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/samples/features/sqlvdi/osimple/osimple.cpp b/samples/features/sqlvdi/osimple/osimple.cpp index 118d080e..12c99f50 100644 --- a/samples/features/sqlvdi/osimple/osimple.cpp +++ b/samples/features/sqlvdi/osimple/osimple.cpp @@ -46,204 +46,210 @@ All Rights Reserved. #include "vdierror.h" // error constants #include "vdiguid.h" // define the interface identifiers. - // IMPORTANT: vdiguid.h can only be included in one source file. - // + // 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 ); +void performTransfer( + IClientVirtualDevice* vd, + int backup); -HANDLE execSQL (int doBackup); -int checkSQL (HANDLE); +HANDLE execSQL(bool doBackup); +bool checkSQL(HANDLE); // Using a GUID for the VDS Name is a good way to assure uniqueness. // -WCHAR wVdsName [50]; +WCHAR wVdsName[50]; //------------------------------------------------------------ // // Mainline // -int main (int argc, char *argv[]) +int main(int argc, char* argv[]) { - HRESULT hr; - IClientVirtualDeviceSet2* vds = NULL ; - IClientVirtualDevice* vd=NULL; + HRESULT hr; + IClientVirtualDeviceSet2* vds = nullptr; + IClientVirtualDevice* vd = nullptr; - VDConfig config; - int badParm=TRUE; - int doBackup; - HANDLE hThread = NULL; + VDConfig config; + bool badParm = true; + bool doBackup; + HANDLE hThread = nullptr; - // 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; - } - } + // Check the input parm + // + if (argc == 2) + { + char param = toupper(argv[1][0]); - if (badParm) - { - printf ("useage: osimple {B|R}\n" - "Demonstrate a Backup or Restore using the Virtual Device Interface & ODBC\n"); - exit (1); - } + if (param == 'B') + { + doBackup = true; + badParm = false; + } + else if (param == 'R') + { + doBackup = false; + badParm = false; + } + } - printf ("Performing a %s using a virtual device.\n", - (doBackup) ? "BACKUP" : "RESTORE"); + if (badParm) + { + printf("usage: osimple {B|R}\n" + "Demonstrate a Backup or Restore using the Virtual Device Interface & ODBC\n"); + exit(1); + } - // Initialize COM Library - // Note: _WIN32_DCOM must be defined during the compile. - // - hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); + printf("Performing a %s using a virtual device.\n", + (doBackup) ? "BACKUP" : "RESTORE"); - if (!SUCCEEDED (hr)) - { - printf ("Coinit fails: x%X\n", hr); - exit (1); - } + // Initialize COM Library + // Note: _WIN32_DCOM must be defined during the compile. + // + hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); - // 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 (FAILED(hr)) + { + printf("Coinit fails: x%X\n", hr); + exit(1); + } - 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; - } + // 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, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IClientVirtualDeviceSet2, + (void**)&vds); - // 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; + if (FAILED(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); + 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; - } + // Create the virtual device set + // for use by the default instance. + // + // To use a named instance, change the + // first parameter in CreateEx to your instance's name. + // + hr = vds->CreateEx(nullptr, wVdsName, &config); + if (FAILED(hr)) + { + printf("VDS::Create fails: x%X", hr); + goto exit; + } - // Send the SQL command, by starting a thread to handle the ODBC - // + // 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; - } + hThread = execSQL(doBackup); + if (hThread == nullptr) + { + printf("execSQL failed.\n"); + goto shutdown; + } - // Wait for the server to connect, completing the configuration. - // - printf ("\nWaiting for SQLServer to respond...\n"); + // 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) - { + while (FAILED(hr = vds->GetConfiguration(1000, &config))) + { + if (hr == VD_E_TIMEOUT) + { // Check on the SQL thread // - DWORD rc = WaitForSingleObject (hThread, 1000); + DWORD rc = WaitForSingleObject(hThread, 1000); if (rc == WAIT_OBJECT_0) { - printf ("SQL command failed before VD transfer\n"); + printf("SQL command failed before VD transfer\n"); goto shutdown; } if (rc == WAIT_TIMEOUT) { continue; } - printf ("Check on SQL failed: %d\n", rc); + 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("VDS::Getconfig fails: x%X\n", hr); + goto shutdown; + } + + // Open the single device in the set. + // + hr = vds->OpenDevice(wVdsName, &vd); + if (FAILED(hr)) + { + printf("VDS::OpenDevice fails: x%X\n", hr); + goto shutdown; + } + + printf("\nPerforming data transfer...\n"); + + performTransfer(vd, doBackup); + - printf ("\nPerforming data transfer...\n"); - - performTransfer (vd, doBackup); - - shutdown: - // Close the set - // - vds->Close (); + // Close the set + // + vds->Close(); - // Obtain the SQL completion information - // - if (hThread != NULL) + // Obtain the SQL completion information + // + if (hThread != nullptr) { - if (checkSQL (hThread)) + if (checkSQL(hThread)) printf("\nThe SQL command executed successfully.\n"); else printf("\nThe SQL command failed.\n"); - CloseHandle (hThread); + CloseHandle(hThread); } - // COM reference counting: Release the interface. - // - vds->Release () ; + // COM reference counting: Release the interface. + // + vds->Release(); exit: - // Uninitialize COM Library - // - CoUninitialize () ; + // Uninitialize COM Library + // + CoUninitialize(); - return 0 ; + return 0; } //--------------------------------------------------------------------------- @@ -255,93 +261,93 @@ exit: // operations like RESTORE which can sometimes recover from // errors (error messages will be followed by the 3014 success message). // -void ProcessMessages ( +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. + SQLHANDLE handle, // ODBC handle + bool ConnInd, // TRUE if sucessful connection made + bool* 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]; + RETCODE plm_retcode = SQL_SUCCESS; + SQLWCHAR plm_szSqlState[SQL_SQLSTATE_SIZE + 1]; + SQLWCHAR 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; + SQLBIGINT plm_Rownumber = 0; + USHORT plm_SS_Line; + SQLSMALLINT plm_cbSS_Procname, plm_cbSS_Srvname; + SQLWCHAR plm_SS_Procname[MAXNAME], plm_SS_Srvname[MAXNAME]; - while (plm_retcode != SQL_NO_DATA_FOUND) + 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); + 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) + // 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) + 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_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_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_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_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_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); + 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("Msg %d, SevLevel %d, State %d, SQLState %ls\n", + plm_pfNativeError, + plm_SS_Severity, + plm_SS_MsgState, + plm_szSqlState); + } - printf ("%s\n", plm_szErrorMsg); + printf_s("%ls\n", plm_szErrorMsg); - if (pBackupSuccess && plm_pfNativeError == 3014) - { - *pBackupSuccess = TRUE; - } - } + if (pBackupSuccess && plm_pfNativeError == 3014) + { + *pBackupSuccess = TRUE; + } + } - plm_cRecNmbr++; //Increment to next diagnostic record. - } // End while. + plm_cRecNmbr++; //Increment to next diagnostic record. + } // End while. } @@ -352,99 +358,103 @@ void ProcessMessages ( // Returns TRUE if a successful backup/restore is performed. // unsigned __stdcall -SQLRoutine (void *parms) +SQLRoutine(void* parms) { - int doBackup = (int)parms; - - char sqlCommand [1024]; // way more space than we'll need. - int successDetected = FALSE; + bool doBackup = (bool)parms; + + wchar_t sqlCommand[1024]; // way more space than we'll need. + bool successDetected = false; // ODBC handles // - SQLHENV henv = NULL; - SQLHDBC hdbc = NULL; - SQLHSTMT hstmt = NULL; + SQLHENV henv = nullptr; + SQLHDBC hdbc = nullptr; + SQLHSTMT hstmt = nullptr; - sprintf (sqlCommand, "%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'", - (doBackup) ? "BACKUP" : "RESTORE", - (doBackup) ? "TO" : "FROM", + swprintf_s(sqlCommand, L"%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'", + (doBackup) ? L"BACKUP" : L"RESTORE", + (doBackup) ? L"TO" : L"FROM", wVdsName); - int sentSQL = FALSE; - int rc; + bool sentSQL = false; + int rc; - #define MAX_CONN_OUT 1024 - SQLCHAR szOutConn[MAX_CONN_OUT]; - SQLSMALLINT cbOutConn; + #define MAX_CONN_OUT 1024 + SQLWCHAR szOutConn[MAX_CONN_OUT]; + SQLSMALLINT cbOutConn; - // Initialize the ODBC environment. - // - if (SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv) == SQL_ERROR) - goto exit; + // Initialize the ODBC environment. + // + if (SQLAllocHandle(SQL_HANDLE_ENV, nullptr, &henv) == SQL_ERROR) + goto exit; - // This is an ODBC v3 application - // - SQLSetEnvAttr (henv, SQL_ATTR_ODBC_VERSION, (void*) SQL_OV_ODBC3, SQL_IS_INTEGER); + // 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; - } + // 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); + // 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. + // + // To use a named instance, change "SERVER=." to "SERVER=.\\instance_name" + // - if (rc == SQL_ERROR) - { - SQLCHAR szSqlState[20]; - SQLINTEGER ssErr; - SQLCHAR szErrorMsg [MAX_CONN_OUT]; - SQLSMALLINT cbErrorMsg; + rc = SQLDriverConnectW( + hdbc, + nullptr, // no diaglogs please + const_cast(L"DRIVER={SQL Server};Trusted_Connection=yes;SERVER=."), + SQL_NTS, + szOutConn, + MAX_CONN_OUT, + &cbOutConn, + SQL_DRIVER_NOPROMPT); - printf ("Connect fails\n"); + if (rc == SQL_ERROR) + { + SQLWCHAR szSqlState[20]; + SQLINTEGER ssErr; + SQLWCHAR szErrorMsg[MAX_CONN_OUT]; + SQLSMALLINT cbErrorMsg; - rc = SQLError ( - henv, hdbc, SQL_NULL_HSTMT, - szSqlState, - &ssErr, - szErrorMsg, - MAX_CONN_OUT, - &cbErrorMsg); + printf("Connect fails\n"); - printf ("msg=%s\n", szErrorMsg); + rc = SQLError( + henv, hdbc, SQL_NULL_HSTMT, + szSqlState, + &ssErr, + szErrorMsg, + MAX_CONN_OUT, + &cbErrorMsg); - goto exit; - } + printf("msg=%ls\n", szErrorMsg); - // Get a statement handle - // - if (SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt) == SQL_ERROR) - { - printf ("Failed to get statement handle\n"); + goto exit; + } - ProcessMessages (SQL_HANDLE_DBC, hdbc, TRUE, NULL); - goto exit; - } + // Get a statement handle + // + if (SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt) == SQL_ERROR) + { + printf("Failed to get statement handle\n"); - // Execute the SQL - // - printf ("Executing %s\n", sqlCommand); + ProcessMessages(SQL_HANDLE_DBC, hdbc, true, nullptr); + goto exit; + } - rc = SQLExecDirect (hstmt, (SQLCHAR*)sqlCommand, SQL_NTS); + // Execute the SQL + // + printf_s("Executing %ls\n", sqlCommand); + + rc = SQLExecDirectW(hstmt, const_cast(sqlCommand), SQL_NTS); // Extract all the resulting messages // @@ -454,72 +464,72 @@ SQLRoutine (void *parms) { 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. - // + 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_NEED_DATA: - case SQL_INVALID_HANDLE: - case SQL_STILL_EXECUTING: - default: - successDetected = FALSE; - printf ("Unexpected SQLExec result %d\n", rc); - goto exit; + case SQL_SUCCESS_WITH_INFO: + ProcessMessages(SQL_HANDLE_STMT, hstmt, true, nullptr); + // 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); + rc = SQLMoreResults(hstmt); } exit: // Release the ODBC resources. // - if (hstmt != NULL) - { - SQLFreeHandle(SQL_HANDLE_STMT, hstmt); - hstmt = NULL; - } + if (hstmt != nullptr) + { + SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + hstmt = nullptr; + } - if (hdbc != NULL) - { - SQLDisconnect(hdbc); - SQLFreeHandle(SQL_HANDLE_DBC, hdbc); - hdbc = NULL; - } + if (hdbc != nullptr) + { + SQLDisconnect(hdbc); + SQLFreeHandle(SQL_HANDLE_DBC, hdbc); + hdbc = nullptr; + } - if (henv != NULL) - { - SQLFreeHandle(SQL_HANDLE_ENV, henv); - henv = NULL; - } + if (henv != nullptr) + { + SQLFreeHandle(SQL_HANDLE_ENV, henv); + henv = nullptr; + } - return successDetected; + return successDetected; } @@ -529,16 +539,16 @@ exit: // // Return the thread handle (NULL on error). // -HANDLE execSQL (int doBackup) +HANDLE execSQL(bool doBackup) { unsigned int threadId; HANDLE hThread; - hThread = (HANDLE)_beginthreadex ( - NULL, 0, SQLRoutine, (void*)doBackup, 0, &threadId); - if (hThread == NULL) + hThread = (HANDLE)_beginthreadex( + nullptr, 0, SQLRoutine, (void*)doBackup, 0, &threadId); + if (hThread == nullptr) { - printf ("Failed to create thread. errno is %d\n", errno); + printf("Failed to create thread. errno is %d\n", errno); } return hThread; } @@ -548,23 +558,23 @@ HANDLE execSQL (int doBackup) // checkSQL: Wait for the T-SQL to complete, // returns TRUE if statement successfully executed. // -int checkSQL (HANDLE hThread) +bool checkSQL(HANDLE hThread) { - if (hThread == NULL) - return FALSE; + if (hThread == nullptr) + return false; - DWORD rc = WaitForSingleObject (hThread, INFINITE); + DWORD rc = WaitForSingleObject(hThread, INFINITE); if (rc != WAIT_OBJECT_0) { - printf ("checkSQL failed: %d\n", rc); - return FALSE; + printf("checkSQL failed: %d\n", rc); + return false; } - if (!GetExitCodeThread (hThread, &rc)) + if (!GetExitCodeThread(hThread, &rc)) { - printf ("failed to get exit code: %d\n", GetLastError ()); - return FALSE; + printf("failed to get exit code: %d\n", GetLastError()); + return false; } - return rc == TRUE; + return rc == true; } @@ -576,84 +586,84 @@ int checkSQL (HANDLE hThread) // 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 ) +void performTransfer( + IClientVirtualDevice* vd, + int backup) { - FILE * fh; - char* fname = "superbak.dmp"; - VDC_Command * cmd; - DWORD completionCode; - DWORD bytesTransferred; - HRESULT hr; + FILE* fh; + char* fname = (char*)"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))) + errno_t error = fopen_s(&fh, fname, (backup) ? "wb" : "rb"); + if (error != 0) { - 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; + printf("Failed to open: %s\n", fname); + return; + } - 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; + 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_Flush: - fflush (fh); - completionCode = ERROR_SUCCESS; - break; - - case VDC_ClearError: - completionCode = ERROR_SUCCESS; - 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; - default: - // If command is unknown... - completionCode = ERROR_NOT_SUPPORTED; - } + case VDC_Flush: + fflush(fh); + completionCode = ERROR_SUCCESS; + break; - hr = vd->CompleteCommand (cmd, completionCode, bytesTransferred, 0); - if (!SUCCEEDED (hr)) - { - printf ("Completion Failed: x%X\n", hr); - break; - } - } + case VDC_ClearError: + completionCode = ERROR_SUCCESS; + 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"); - } + default: + // If command is unknown... + completionCode = ERROR_NOT_SUPPORTED; + } - fclose (fh); + hr = vd->CompleteCommand(cmd, completionCode, bytesTransferred, 0); + if (FAILED(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 deleted file mode 100644 index 80794401..00000000 --- a/samples/features/sqlvdi/osimple/osimple.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# 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 deleted file mode 100644 index 52cd0ba3..00000000 --- a/samples/features/sqlvdi/osimple/osimple.dsw +++ /dev/null @@ -1,29 +0,0 @@ -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/osimple/osimple.vcxproj b/samples/features/sqlvdi/osimple/osimple.vcxproj new file mode 100644 index 00000000..aae1e09a --- /dev/null +++ b/samples/features/sqlvdi/osimple/osimple.vcxproj @@ -0,0 +1,142 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {a0d4d328-678f-46d3-8af1-3530d8c55507} + osimple + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + false + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\include + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/features/sqlvdi/osimple/osimple.vcxproj.filters b/samples/features/sqlvdi/osimple/osimple.vcxproj.filters new file mode 100644 index 00000000..ca1fc059 --- /dev/null +++ b/samples/features/sqlvdi/osimple/osimple.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/samples/features/sqlvdi/simple/simple.cpp b/samples/features/sqlvdi/simple/simple.cpp index 60e1bff4..e9aa57f6 100644 --- a/samples/features/sqlvdi/simple/simple.cpp +++ b/samples/features/sqlvdi/simple/simple.cpp @@ -37,193 +37,193 @@ All Rights Reserved. #include "vdierror.h" // error constants #include "vdiguid.h" // define the interface identifiers. - // IMPORTANT: vdiguid.h can only be included in one source file. - // + // IMPORTANT: vdiguid.h can only be included in one source file. + // +void performTransfer( + IClientVirtualDevice* vd, + bool backup); -void performTransfer ( - IClientVirtualDevice* vd, - int backup ); - -int execSQL (int doBackup); +int execSQL(bool doBackup); // Using a GUID for the VDS Name is a good way to assure uniqueness. // -WCHAR wVdsName [50]; +WCHAR wVdsName[50]; // // main function // -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { - HRESULT hr; - IClientVirtualDeviceSet2* vds = NULL ; - IClientVirtualDevice* vd=NULL; + HRESULT hr; + IClientVirtualDeviceSet2* vds = nullptr; + IClientVirtualDevice* vd = nullptr; - VDConfig config; - int badParm=TRUE; - int doBackup; - int hProcess; - int termCode; + VDConfig config; + bool badParm = true; + bool doBackup; + bool isUnnamed = false; + 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; - } - } + // Check the input parm + // + if (argc == 2) + { + char param = toupper(argv[1][0]); - if (badParm) - { - printf ("useage: simple {B|R}\n" - "Demonstrate a Backup or Restore using the Virtual Device Interface\n"); - exit (1); - } + if (param == 'B') + { + doBackup = true; + badParm = false; + } + else if (param == 'R') + { + doBackup = false; + badParm = false; + } + } - // Initialize COM Library - // Note: _WIN32_DCOM must be defined during the compile. - // - hr = CoInitializeEx (NULL, COINIT_MULTITHREADED); + if (badParm) + { + printf("usage: simple {B|R}\n" + "Demonstrate a Backup or Restore using the Virtual Device Interface\n"); + exit(1); + } - if (!SUCCEEDED (hr)) - { - printf ("Coinit fails: x%X\n", hr); - exit (1); - } + // Initialize COM Library + // Note: _WIN32_DCOM must be defined during the compile. + // + hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); - // 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 (FAILED(hr)) + { + printf("Coinit fails: x%X\n", hr); + exit(1); + } - 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; - } + // Get an interface to the device set. + hr = CoCreateInstance( + CLSID_MSSQL_ClientVirtualDeviceSet, + nullptr, + CLSCTX_INPROC_SERVER, + IID_IClientVirtualDeviceSet2, + (void**)&vds); - // 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; + if (FAILED(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); + CoCreateGuid(&vdsId); + StringFromGUID2(vdsId, wVdsName, 49); - // Create the virtual device set + // Create the virtual device set // for use by the default instance. - // Change the first parameter to identify a named instance. + // + // To use a named instance, change the + // first parameter in CreateEx to your instance's name. // - hr = vds->CreateEx (NULL, wVdsName, &config); - if (!SUCCEEDED (hr)) - { - printf ("VDS::Create fails: x%X", hr); - goto exit; - } + hr = vds->CreateEx(nullptr, wVdsName, &config); + if (FAILED(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"); + // 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; - } + 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; - } + // Wait for the server to connect, completing the configuration. + // + hr = vds->GetConfiguration(10000, &config); + if (FAILED(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 (FAILED(hr)) + { + printf("VDS::OpenDevice fails: x%X\n", hr); + goto shutdown; + } + + printf("\nPerforming data transfer...\n"); + + performTransfer(vd, doBackup); - // 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 (); + // 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); - } + // Obtain the SQL completion information, by waiting for isql to exit. + // + if (hProcess == _cwait(&termCode, hProcess, 0)) + { + 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 () ; + // 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 () ; + // Uninitialize COM Library + // + CoUninitialize(); - return 0 ; + return 0; } // @@ -233,116 +233,115 @@ exit: // -1 : failed to spawn // else : a "process handle" // -int execSQL (int doBackup) +int execSQL(bool doBackup) { - char sqlCommand [1024]; // plenty of space for our purpose + wchar_t sqlCommand[1024]; // plenty of space for our purpose - sprintf (sqlCommand, "-Q\"%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'\"", - (doBackup) ? "BACKUP" : "RESTORE", - (doBackup) ? "TO" : "FROM", + // To use a named instance, change "-S ." to "-S .\\instance_name" + swprintf_s(sqlCommand, L"-S . -Q\"%s DATABASE PUBS %s VIRTUAL_DEVICE='%ls'\"", + (doBackup) ? L"BACKUP" : L"RESTORE", + (doBackup) ? L"TO" : L"FROM", wVdsName); - int rc; + intptr_t rc; - printf ("spawning osql to execute: %s\n", sqlCommand); + wprintf(L"spawning osql to execute: %ls\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. + // 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); + rc = _wspawnlp(_P_NOWAIT, L"osql", L"osql", L"-E", L"-b", + sqlCommand, NULL); - if (rc == -1) - { - printf ("Spawn failed with error: %d\n", errno); - } - - return (rc); + 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 ) +void performTransfer( + IClientVirtualDevice* vd, + bool backup) { - FILE * fh; - char* fname = "superbak.dmp"; - VDC_Command * cmd; - DWORD completionCode; - DWORD bytesTransferred; - HRESULT hr; + FILE* fh; + char* fname = (char*)"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; - } + errno_t error = fopen_s(&fh, fname, (backup) ? "wb" : "rb"); + if (error != 0) + { + 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; + 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_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_Flush: + fflush(fh); + completionCode = ERROR_SUCCESS; + break; - default: - // If command is unknown... - completionCode = ERROR_NOT_SUPPORTED; - } + case VDC_ClearError: + completionCode = ERROR_SUCCESS; + break; - hr = vd->CompleteCommand (cmd, completionCode, bytesTransferred, 0); - if (!SUCCEEDED (hr)) - { - printf ("Completion Failed: x%X\n", hr); - break; - } - } + default: + // If command is unknown... + completionCode = ERROR_NOT_SUPPORTED; + } - 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); -} + hr = vd->CompleteCommand(cmd, completionCode, bytesTransferred, 0); + if (FAILED(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); +} \ No newline at end of file diff --git a/samples/features/sqlvdi/simple/simple.dsp b/samples/features/sqlvdi/simple/simple.dsp deleted file mode 100644 index d759c378..00000000 --- a/samples/features/sqlvdi/simple/simple.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# 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 deleted file mode 100644 index f38a9abf..00000000 --- a/samples/features/sqlvdi/simple/simple.dsw +++ /dev/null @@ -1,29 +0,0 @@ -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/simple/simple.vcxproj b/samples/features/sqlvdi/simple/simple.vcxproj new file mode 100644 index 00000000..65fd7f65 --- /dev/null +++ b/samples/features/sqlvdi/simple/simple.vcxproj @@ -0,0 +1,141 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {13df2fa4-99d2-44ac-b218-3463730b6f08} + simple + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions); + true + ..\include + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/features/sqlvdi/simple/simple.vcxproj.filters b/samples/features/sqlvdi/simple/simple.vcxproj.filters new file mode 100644 index 00000000..3a45a431 --- /dev/null +++ b/samples/features/sqlvdi/simple/simple.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + \ No newline at end of file diff --git a/samples/features/sqlvdi/snapshot/snapshot.cpp b/samples/features/sqlvdi/snapshot/snapshot.cpp index be8cf262..62d76119 100644 --- a/samples/features/sqlvdi/snapshot/snapshot.cpp +++ b/samples/features/sqlvdi/snapshot/snapshot.cpp @@ -46,57 +46,60 @@ All Rights Reserved. #include "vdierror.h" // error constants #include "vdiguid.h" // define the interface identifiers. - // IMPORTANT: vdiguid.h can only be included in one source file. - // + // 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 ); +void performTransfer( + IClientVirtualDeviceSet2* vds, + IClientVirtualDevice* vd, + int backup); -HANDLE execSQL (int doBackup, char* pInstanceName, char* pDbName, WCHAR* pVdsName); -int checkSQL (HANDLE); +HANDLE execSQL(bool doBackup, WCHAR* pInstanceName, WCHAR* pDbName, WCHAR* pVdsName); +bool checkSQL(HANDLE); -BOOL -ynPrompt (char *str); +bool ynPrompt(const char* str); //------------------------------------------------------------ // // Mainline // int __cdecl -main (int argc, char *argv[]) +main(int argc, char* argv[]) { - HRESULT hr; - IClientVirtualDeviceSet2* vds = NULL ; - IClientVirtualDevice* vd=NULL; + HRESULT hr; + IClientVirtualDeviceSet2* vds = nullptr; + IClientVirtualDevice* vd = nullptr; - VDConfig config; - int badParm=TRUE; - int doBackup; - HANDLE hThread = NULL; - char* pDbName = NULL; - char* pInstanceName = NULL; + VDConfig config; + bool badParm = true; + bool doBackup; + HANDLE hThread = nullptr; + char* pDbName = nullptr; + char* pInstanceName = nullptr; + WCHAR wInstanceName[128] = { 0 }; + int rc = 0; - // 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; - } + // Check the input parm + // + if (argc >= 3) + { + char param = toupper(argv[1][0]); + + if (param == 'B') + { + doBackup = true; + badParm = false; + } + else if (param == 'R') + { + doBackup = false; + badParm = false; + } pDbName = argv[2]; @@ -104,173 +107,177 @@ main (int argc, char *argv[]) { 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" + if (badParm) + { + printf("usage: 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); - } + exit(1); + } - printf ("Performing a %s of %s on %s using a VIRTUAL_DEVICE.\n", - (doBackup) ? "BACKUP" : "RESTORE", + 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); + // Initialize COM Library + // Note: _WIN32_DCOM must be defined during the compile. + // + hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED); - if (!SUCCEEDED (hr)) - { - printf ("Coinit fails: x%X\n", hr); - exit (1); - } + if (FAILED(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); + // 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, + nullptr, + 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; - } + if (FAILED(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; + // 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); + WCHAR wVdsName[50]; + CoCreateGuid(&vdsId); + StringFromGUID2(vdsId, wVdsName, 49); - // Create the virtual device set - // Notice that we only support unicode interfaces + // 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), + rc = MultiByteToWideChar(CP_ACP, 0, + pInstanceName, strlen(pInstanceName), wInstanceName, 127); } - wInstanceName [rc] = 0; + wInstanceName[rc] = 0; - hr = vds->CreateEx (wInstanceName, wVdsName, &config); - if (!SUCCEEDED (hr)) - { - printf ("VDS::Create fails: x%X", hr); - goto exit; - } + hr = vds->CreateEx(wInstanceName, wVdsName, &config); + if (FAILED(hr)) + { + printf("VDS::Create fails: x%X", hr); + goto exit; + } - // Send the SQL command, by starting a thread to handle the ODBC - // + // 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; - } + WCHAR wDbName[128]; + MultiByteToWideChar(CP_ACP, 0, + pDbName, -1, + wDbName, 127); - // Wait for the server to connect, completing the configuration. - // - printf ("\nWaiting for SQLServer to respond...\n"); + hThread = execSQL(doBackup, wInstanceName, wDbName, wVdsName); + if (hThread == nullptr) + { + printf("execSQL failed.\n"); + goto shutdown; + } - while (!SUCCEEDED (hr=vds->GetConfiguration (1000, &config))) - { - if (hr == VD_E_TIMEOUT) - { + // Wait for the server to connect, completing the configuration. + // + printf("\nWaiting for SQLServer to respond...\n"); + + while (FAILED(hr = vds->GetConfiguration(1000, &config))) + { + if (hr == VD_E_TIMEOUT) + { // Check on the SQL thread // - DWORD rc = WaitForSingleObject (hThread, 1000); + DWORD rc = WaitForSingleObject(hThread, 1000); if (rc == WAIT_OBJECT_0) { - printf ("SQL command failed before VD transfer\n"); + printf("SQL command failed before VD transfer\n"); goto shutdown; } if (rc == WAIT_TIMEOUT) { continue; } - printf ("Check on SQL failed: %d\n", rc); + 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("VDS::Getconfig fails: x%X\n", hr); + goto shutdown; + } + + // Open the single device in the set. + // + hr = vds->OpenDevice(wVdsName, &vd); + if (FAILED(hr)) + { + printf("VDS::OpenDevice fails: x%X\n", hr); + goto shutdown; + } + + printf("\nPerforming data transfer...\n"); + + performTransfer(vds, vd, doBackup); + - printf ("\nPerforming data transfer...\n"); - - performTransfer (vds, vd, doBackup); - - shutdown: - // Close the set - // - vds->Close (); + // Close the set + // + vds->Close(); - // Obtain the SQL completion information - // - if (hThread != NULL) + // Obtain the SQL completion information + // + if (hThread != nullptr) { - if (checkSQL (hThread)) + if (checkSQL(hThread)) printf("\nThe SQL command executed successfully.\n"); else printf("\nThe SQL command failed.\n"); - CloseHandle (hThread); + CloseHandle(hThread); } - // COM reference counting: Release the interface. - // - vds->Release () ; + // COM reference counting: Release the interface. + // + vds->Release(); exit: - // Uninitialize COM Library - // - CoUninitialize () ; + // Uninitialize COM Library + // + CoUninitialize(); - return 0 ; + return 0; } //--------------------------------------------------------------------------- @@ -282,93 +289,93 @@ exit: // operations like RESTORE which can sometimes recover from // errors (error messages will be followed by the 3014 success message). // -void ProcessMessages ( +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. + SQLHANDLE handle, // ODBC handle + bool ConnInd, // TRUE if sucessful connection made + bool* 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]; + RETCODE plm_retcode = SQL_SUCCESS; + SQLWCHAR plm_szSqlState[SQL_SQLSTATE_SIZE + 1]; + SQLWCHAR 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; + SQLBIGINT 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) + 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); + 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) + // 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) + 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_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_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_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_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_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); + 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("Msg %ld, SevLevel %ld, State %ld, SQLState %ls\n", + plm_pfNativeError, + plm_SS_Severity, + plm_SS_MsgState, + plm_szSqlState); + } - printf ("%s\n", plm_szErrorMsg); + printf("%ls\n", plm_szErrorMsg); - if (pBackupSuccess && plm_pfNativeError == 3014) - { - *pBackupSuccess = TRUE; - } - } + if (pBackupSuccess && plm_pfNativeError == 3014) + { + *pBackupSuccess = TRUE; + } + } - plm_cRecNmbr++; //Increment to next diagnostic record. - } // End while. + plm_cRecNmbr++; //Increment to next diagnostic record. + } // End while. } @@ -380,133 +387,122 @@ void ProcessMessages ( // struct PARMS { - int doBackup; - char* pInstanceName; - char* pDbName; + bool doBackup; + WCHAR* pInstanceName; + WCHAR* pDbName; WCHAR* pVdsName; }; unsigned __stdcall -SQLRoutine (void* input) +SQLRoutine(void* input) { - PARMS* parms = (PARMS*)input; + PARMS* parms = (PARMS*)input; - SQLCHAR* pSQLText; // the command being executed. - int successDetected = FALSE; + SQLWCHAR* pSQLText; // the command being executed. + bool successDetected = false; // ODBC handles // - SQLHENV henv = NULL; - SQLHDBC hdbc = NULL; - SQLHSTMT hstmt = NULL; + SQLHENV henv = nullptr; + SQLHDBC hdbc = nullptr; + SQLHSTMT hstmt = nullptr; - char sqlCommand [1024]; + WCHAR sqlCommand[1024]; + SQLWCHAR connectString[200] = { 0 }; - int sentSQL = FALSE; - int rc; + bool 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 + #define MAX_CONN_OUT 1024 + SQLWCHAR szOutConn[MAX_CONN_OUT] = { 0 }; + SQLSMALLINT cbOutConn; // Generate the command to execute // - sprintf (sqlCommand, "%s DATABASE [%s] %s VIRTUAL_DEVICE='%s' WITH SNAPSHOT", - parms->doBackup ? "BACKUP" : "RESTORE", + swprintf_s(sqlCommand, L"%ls DATABASE [%ls] %ls VIRTUAL_DEVICE='%ls' WITH SNAPSHOT", + parms->doBackup ? L"BACKUP" : L"RESTORE", parms->pDbName, - parms->doBackup ? "TO" : "FROM", - aVdsName); + parms->doBackup ? L"TO" : L"FROM", + parms->pVdsName); - // Initialize the ODBC environment. - // - if (SQLAllocHandle (SQL_HANDLE_ENV, NULL, &henv) == SQL_ERROR) - goto exit; + // 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); + // 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) + // Allocate a connection handle + // + if (SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc) == SQL_ERROR) { - sprintf (connectString+strlen(connectString), "\\%s", parms->pInstanceName); + printf("AllocHandle on DBC failed."); + goto exit; } - printf ("\n\nConnecting with: %s\n", connectString); + wcscpy_s(connectString, 200, L"DRIVER={SQL Server};Trusted_Connection=yes;SERVER=."); + if (parms->pInstanceName) + { + swprintf_s(connectString + wcslen(connectString), 200 - wcslen(connectString), L"\\%ls", parms->pInstanceName); + } - // Connect to the server using Trusted connection. - // Trusted connection uses integrated NT security. + printf("\n\nConnecting with: %ls\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); + rc = SQLDriverConnect( + hdbc, + nullptr, // no diaglogs please + 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; + if (rc == SQL_ERROR) + { + SQLWCHAR szSqlState[20]; + SQLINTEGER ssErr; + SQLWCHAR szErrorMsg[MAX_CONN_OUT]; + SQLSMALLINT cbErrorMsg; - printf ("Connect fails\n"); + printf("Connect fails\n"); - rc = SQLError ( - henv, hdbc, SQL_NULL_HSTMT, - szSqlState, - &ssErr, - szErrorMsg, - MAX_CONN_OUT, - &cbErrorMsg); + rc = SQLError( + henv, hdbc, SQL_NULL_HSTMT, + szSqlState, + &ssErr, + szErrorMsg, + MAX_CONN_OUT, + &cbErrorMsg); - printf ("msg=%s\n", szErrorMsg); + printf("msg=%ls\n", szErrorMsg); - goto exit; - } + goto exit; + } - // Get a statement handle - // - if (SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt) == SQL_ERROR) - { - printf ("Failed to get statement handle\n"); + // 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; - } + ProcessMessages(SQL_HANDLE_DBC, hdbc, true, nullptr); + goto exit; + } - // Execute the SQL - // - printf ("\n\nExecuting SQL: %s\n", sqlCommand); + // Execute the SQL + // + printf("\n\nExecuting SQL: %ls\n", sqlCommand); - pSQLText = (SQLCHAR*)sqlCommand; + pSQLText = sqlCommand; - rc = SQLExecDirect (hstmt, pSQLText, SQL_NTS); + rc = SQLExecDirect(hstmt, pSQLText, SQL_NTS); // Extract all the resulting messages // @@ -516,72 +512,72 @@ SQLRoutine (void* input) { 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. - // + 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_NEED_DATA: - case SQL_INVALID_HANDLE: - case SQL_STILL_EXECUTING: - default: - successDetected = FALSE; - printf ("Unexpected SQLExec result %d\n", rc); - goto exit; + 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); + rc = SQLMoreResults(hstmt); } exit: // Release the ODBC resources. // - if (hstmt != NULL) - { - SQLFreeHandle(SQL_HANDLE_STMT, hstmt); - hstmt = NULL; - } + if (hstmt != nullptr) + { + SQLFreeHandle(SQL_HANDLE_STMT, hstmt); + hstmt = nullptr; + } - if (hdbc != NULL) - { - SQLDisconnect(hdbc); - SQLFreeHandle(SQL_HANDLE_DBC, hdbc); - hdbc = NULL; - } + if (hdbc != nullptr) + { + SQLDisconnect(hdbc); + SQLFreeHandle(SQL_HANDLE_DBC, hdbc); + hdbc = nullptr; + } - if (henv != NULL) - { - SQLFreeHandle(SQL_HANDLE_ENV, henv); - henv = NULL; - } + if (henv != nullptr) + { + SQLFreeHandle(SQL_HANDLE_ENV, henv); + henv = nullptr; + } - return successDetected; + return successDetected; } @@ -591,7 +587,7 @@ exit: // // Return the thread handle (NULL on error). // -HANDLE execSQL (int doBackup, char* pInstanceName, char* pDbName, WCHAR* pVDName) +HANDLE execSQL(bool doBackup, WCHAR* pInstanceName, WCHAR* pDbName, WCHAR* pVDName) { unsigned int threadId; HANDLE hThread; @@ -602,11 +598,11 @@ HANDLE execSQL (int doBackup, char* pInstanceName, char* pDbName, WCHAR* pVDName parms.pInstanceName = pInstanceName; parms.pVdsName = pVDName; - hThread = (HANDLE)_beginthreadex ( - NULL, 0, SQLRoutine, (void*)&parms, 0, &threadId); - if (hThread == NULL) + hThread = (HANDLE)_beginthreadex( + nullptr, 0, SQLRoutine, (void*)&parms, 0, &threadId); + if (hThread == nullptr) { - printf ("Failed to create thread. errno is %d\n", errno); + printf("Failed to create thread. errno is %d\n", errno); } return hThread; } @@ -616,23 +612,23 @@ HANDLE execSQL (int doBackup, char* pInstanceName, char* pDbName, WCHAR* pVDName // checkSQL: Wait for the T-SQL to complete, // returns TRUE if statement successfully executed. // -int checkSQL (HANDLE hThread) +bool checkSQL(HANDLE hThread) { - if (hThread == NULL) - return FALSE; + if (hThread == nullptr) + return false; - DWORD rc = WaitForSingleObject (hThread, INFINITE); + DWORD rc = WaitForSingleObject(hThread, INFINITE); if (rc != WAIT_OBJECT_0) { - printf ("checkSQL failed: %d\n", rc); - return FALSE; + printf("checkSQL failed: %d\n", rc); + return false; } - if (!GetExitCodeThread (hThread, &rc)) + if (!GetExitCodeThread(hThread, &rc)) { - printf ("failed to get exit code: %d\n", GetLastError ()); - return FALSE; + printf("failed to get exit code: %d\n", GetLastError()); + return false; } - return rc == TRUE; + return rc == true; } @@ -640,16 +636,20 @@ int checkSQL (HANDLE hThread) // Ask the user a "yes/no" question. // Return TRUE if he answers "yes" // -BOOL -ynPrompt (char *str) +bool ynPrompt(const char* str) { - char line[256]; + char line[256]; - printf ("\n\n%s", str); - line [0] = 0; - gets (line); - printf ("\n\n"); - return (line [0] == 'y' || line [0] == 'Y'); + printf("\n\n%s\n", str); + fgets(line, sizeof(line), stdin); + + // Remove newline character if fgets reads in a newline. + size_t len = strlen(line); + if (len > 0 && line[len - 1] == '\n') { + line[len - 1] = '\0'; + } + + return (line[0] == 'y' || line[0] == 'Y'); } //---------------------------------------------------------------------------------- @@ -658,170 +658,170 @@ ynPrompt (char *str) // 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 ) +void performTransfer( + IClientVirtualDeviceSet2* iVds, + IClientVirtualDevice* vd, + int backup) { - FILE * fh; - char* fname = "snapshot.dmp"; - VDC_Command * cmd; - DWORD completionCode; - DWORD bytesTransferred; - HRESULT hr; + FILE* fh; + char* fname = (char*)"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; - } + errno_t error = fopen_s(&fh, fname, (backup) ? "wb" : "rb"); + if (error != 0) + { + 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. - // + 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; - break; + else + // assume failure is eof + completionCode = ERROR_HANDLE_EOF; + 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. - // + case VDC_Write: + bytesTransferred = fwrite(cmd->buffer, 1, cmd->size, fh); + if (bytesTransferred == cmd->size) + { completionCode = ERROR_SUCCESS; - hr = vd->CompleteCommand (cmd, completionCode, bytesTransferred, 0); - if (!SUCCEEDED (hr)) + } + 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?")) { - printf ("Completion Failed: x%X\n", hr); + 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; - // The only valid command will be a "close" request. - // - hr = vd->GetCommand (INFINITE, &cmd); - if (hr != VD_E_CLOSE) + 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 = nullptr; + + printf("\n*** Make the snapshot now ***\n"); + + while (!ynPrompt("Did you complete the snapshot?")) + { + if (ynPrompt("Do you want to abort?")) { - printf ("Unexpected snapshot termination: x%X\n", hr); - } - else - { - printf ("SQLServer is aware that the snapshot is successful.\n"); + 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 (FAILED(hr)) + { + printf("Completion Failed: x%X\n", hr); return; + } - case VDC_MountSnapshot: - printf ("\n*** Mount the snapshot now ***\n"); + // 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; - while (!ynPrompt ("Did you complete the snapshot?")) + case VDC_MountSnapshot: + printf("\n*** Mount the snapshot now ***\n"); + + while (!ynPrompt("Did you complete the snapshot?")) + { + if (ynPrompt("Do you want to abort?")) { - if (ynPrompt ("Do you want to abort?")) - { - iVds->SignalAbort (); - return; - } + iVds->SignalAbort(); + return; } - completionCode = ERROR_SUCCESS; - break; + } + completionCode = ERROR_SUCCESS; + break; - default: - // If command is unknown... - completionCode = ERROR_NOT_SUPPORTED; - } + 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; - } - } + hr = vd->CompleteCommand(cmd, completionCode, bytesTransferred, 0); + if (FAILED(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) + if (hr != VD_E_CLOSE) { - fclose (fh); + 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 != nullptr) + { + fclose(fh); } } diff --git a/samples/features/sqlvdi/snapshot/snapshot.dsp b/samples/features/sqlvdi/snapshot/snapshot.dsp deleted file mode 100644 index 55f9a285..00000000 --- a/samples/features/sqlvdi/snapshot/snapshot.dsp +++ /dev/null @@ -1,100 +0,0 @@ -# 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 deleted file mode 100644 index 10da226d..00000000 --- a/samples/features/sqlvdi/snapshot/snapshot.dsw +++ /dev/null @@ -1,29 +0,0 @@ -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> -{{{ -}}} - -############################################################################### - diff --git a/samples/features/sqlvdi/snapshot/snapshot.vcxproj b/samples/features/sqlvdi/snapshot/snapshot.vcxproj new file mode 100644 index 00000000..8865b538 --- /dev/null +++ b/samples/features/sqlvdi/snapshot/snapshot.vcxproj @@ -0,0 +1,142 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {f51dacf4-9aba-4f84-a508-041d3c1f2399} + snapshot + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + false + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + ..\include + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/features/sqlvdi/snapshot/snapshot.vcxproj.filters b/samples/features/sqlvdi/snapshot/snapshot.vcxproj.filters new file mode 100644 index 00000000..1f377956 --- /dev/null +++ b/samples/features/sqlvdi/snapshot/snapshot.vcxproj.filters @@ -0,0 +1,33 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file