diff options
-rw-r--r-- | resource.h | 15 | ||||
-rw-r--r-- | usbclerk.cpp | 408 | ||||
-rw-r--r-- | usbclerk.rc | 99 | ||||
-rw-r--r-- | usbclerk.sln | 36 | ||||
-rw-r--r-- | usbclerk.vcproj | 381 | ||||
-rw-r--r-- | usbclerktest.cpp | 41 | ||||
-rw-r--r-- | usbclerktest.vcproj | 347 | ||||
-rw-r--r-- | usbcommon.h | 13 | ||||
-rw-r--r-- | vdlog.cpp | 111 | ||||
-rw-r--r-- | vdlog.h | 93 |
10 files changed, 1544 insertions, 0 deletions
diff --git a/resource.h b/resource.h new file mode 100644 index 0000000..c1243b6 --- /dev/null +++ b/resource.h @@ -0,0 +1,15 @@ +//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by usbservice.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/usbclerk.cpp b/usbclerk.cpp new file mode 100644 index 0000000..68ee009 --- /dev/null +++ b/usbclerk.cpp @@ -0,0 +1,408 @@ +#include <windows.h> +#include <stdio.h> +#include <string.h> +#include <tchar.h> +#include "usbcommon.h" +#include "libwdi.h" +#include "vdlog.h" + +//#define DEBUG_USB_CLERK + +#define USB_CLERK_DISPLAY_NAME TEXT("USB Clerk") +#define USB_CLERK_NAME TEXT("usbclerk") +#define USB_CLERK_DESCRIPTION TEXT("Enables automathic winusb driver signing & install") +#define USB_CLERK_LOAD_ORDER_GROUP TEXT("") +#define USB_CLERK_LOG_PATH TEXT("%susbclerk.log") +#define USB_CLERK_PIPE_TIMEOUT 10000 +#define USB_CLERK_PIPE_BUF_SIZE 1024
+#define USB_DRIVER_PATH "%Swdi_usb_driver" +#define USB_DRIVER_INFNAME_LEN 64 +#define USB_DRIVER_INSTALL_RETRIES 3 +#define USB_DRIVER_INSTALL_INTERVAL 1000 + +class USBClerk { +public: + static USBClerk* get(); + ~USBClerk(); + bool run(); + bool install(); + bool uninstall(); + +private: + USBClerk(); + bool execute(); + bool install_winusb_driver(int vid, int pid); + static DWORD WINAPI control_handler(DWORD control, DWORD event_type, + LPVOID event_data, LPVOID context); + static VOID WINAPI main(DWORD argc, TCHAR * argv[]); + +private: + static USBClerk* _singleton; + SERVICE_STATUS _status; + SERVICE_STATUS_HANDLE _status_handle; + char _wdi_path[MAX_PATH]; + HANDLE _pipe; + bool _running; + VDLog* _log; +}; + +USBClerk* USBClerk::_singleton = NULL; + +USBClerk* USBClerk::get() +{ + if (!_singleton) { + _singleton = new USBClerk(); + } + return (USBClerk*)_singleton; +} + +USBClerk::USBClerk() + : _running (false) + , _status_handle (0) + , _log (NULL) +{ + _singleton = this; +} + +USBClerk::~USBClerk() +{ + delete _log; +} + +bool USBClerk::run() +{ +#ifndef DEBUG_USB_CLERK + SERVICE_TABLE_ENTRY service_table[] = {{USB_CLERK_NAME, main}, {0, 0}}; + return !!StartServiceCtrlDispatcher(service_table); +#else + main(0, NULL); + return true; +#endif +} + +bool USBClerk::install() +{ + bool ret = false; + + SC_HANDLE service_control_manager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); + if (!service_control_manager) { + printf("OpenSCManager failed\n"); + return false; + } + TCHAR path[_MAX_PATH + 1]; + if (!GetModuleFileName(0, path, sizeof(path) / sizeof(path[0]))) { + printf("GetModuleFileName failed\n"); + CloseServiceHandle(service_control_manager); + return false; + } + //FIXME: SERVICE_INTERACTIVE_PROCESS needed for xp only + SC_HANDLE service = CreateService(service_control_manager, USB_CLERK_NAME, + USB_CLERK_DISPLAY_NAME, SERVICE_ALL_ACCESS, + SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, + SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path, + USB_CLERK_LOAD_ORDER_GROUP, 0, 0, 0, 0); + if (service) { + SERVICE_DESCRIPTION descr; + descr.lpDescription = USB_CLERK_DESCRIPTION; + if (!ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &descr)) { + printf("ChangeServiceConfig2 failed\n"); + } + CloseServiceHandle(service); + printf("Service installed successfully\n"); + ret = true; + } else if (GetLastError() == ERROR_SERVICE_EXISTS) { + printf("Service already exists\n"); + ret = true; + } else { + printf("Service not installed successfully, error %d\n", GetLastError()); + } + CloseServiceHandle(service_control_manager); + return ret; +} + +bool USBClerk::uninstall() +{ + bool ret = false; + + SC_HANDLE service_control_manager = OpenSCManager(0, 0, SC_MANAGER_CONNECT); + if (!service_control_manager) { + printf("OpenSCManager failed\n"); + return false; + } + SC_HANDLE service = OpenService(service_control_manager, USB_CLERK_NAME, + SERVICE_QUERY_STATUS | DELETE); + if (!service) { + printf("OpenService failed\n"); + CloseServiceHandle(service_control_manager); + return false; + } + SERVICE_STATUS status; + if (!QueryServiceStatus(service, &status)) { + printf("QueryServiceStatus failed\n"); + } else if (status.dwCurrentState != SERVICE_STOPPED) { + printf("Service is still running\n"); + } else if (DeleteService(service)) { + printf("Service removed successfully\n"); + ret = true; + } else { + switch (GetLastError()) { + case ERROR_ACCESS_DENIED: + printf("Access denied while trying to remove service\n"); + break; + case ERROR_INVALID_HANDLE: + printf("Handle invalid while trying to remove service\n"); + break; + case ERROR_SERVICE_MARKED_FOR_DELETE: + printf("Service already marked for deletion\n"); + break; + } + } + CloseServiceHandle(service); + CloseServiceHandle(service_control_manager); + return ret; +} + +DWORD WINAPI USBClerk::control_handler(DWORD control, DWORD event_type, LPVOID event_data, + LPVOID context) +{ + USBClerk* s = _singleton; + DWORD ret = NO_ERROR; + + switch (control) { + case SERVICE_CONTROL_STOP: + case SERVICE_CONTROL_SHUTDOWN: { + HANDLE pipe; + s->_status.dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus(s->_status_handle, &s->_status); + s->_running = false; + pipe = CreateFile(USB_CLERK_PIPE_NAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + if (pipe != INVALID_HANDLE_VALUE) { + CloseHandle(pipe); + } + break; + } + case SERVICE_CONTROL_INTERROGATE: + SetServiceStatus(s->_status_handle, &s->_status); + break; + default: + ret = ERROR_CALL_NOT_IMPLEMENTED; + } + return ret; +} + +#define USBCLERK_ACCEPTED_CONTROLS \ + (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_SESSIONCHANGE) + +VOID WINAPI USBClerk::main(DWORD argc, TCHAR* argv[]) +{ + USBClerk* s = _singleton; + + SERVICE_STATUS* status; + TCHAR log_path[MAX_PATH]; + TCHAR temp_path[MAX_PATH]; + + if (GetTempPath(MAX_PATH, temp_path)) { + sprintf_s(s->_wdi_path, MAX_PATH, USB_DRIVER_PATH, temp_path); + swprintf_s(log_path, MAX_PATH, USB_CLERK_LOG_PATH, temp_path); + s->_log = VDLog::get(log_path); + } + vd_printf("***Service started***"); + SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); + status = &s->_status; + status->dwServiceType = SERVICE_WIN32; + status->dwCurrentState = SERVICE_STOPPED; + status->dwControlsAccepted = 0; + status->dwWin32ExitCode = NO_ERROR; + status->dwServiceSpecificExitCode = NO_ERROR; + status->dwCheckPoint = 0; + status->dwWaitHint = 0; + s->_status_handle = RegisterServiceCtrlHandlerEx(USB_CLERK_NAME, &USBClerk::control_handler, + NULL); + if (!s->_status_handle) { +#ifndef DEBUG_USB_CLERK + vd_printf("RegisterServiceCtrlHandler failed"); + return; +#endif // DEBUG_USB_CLERK + } + + // service is starting + status->dwCurrentState = SERVICE_START_PENDING; + SetServiceStatus(s->_status_handle, status); + + // service running + status->dwControlsAccepted |= USBCLERK_ACCEPTED_CONTROLS; + status->dwCurrentState = SERVICE_RUNNING; + SetServiceStatus(s->_status_handle, status); + + s->_running = true; + s->execute(); + + // service was stopped + status->dwCurrentState = SERVICE_STOP_PENDING; + SetServiceStatus(s->_status_handle, status); + + // service is stopped + status->dwControlsAccepted &= ~USBCLERK_ACCEPTED_CONTROLS; + status->dwCurrentState = SERVICE_STOPPED; +#ifndef DEBUG_USB_CLERK + SetServiceStatus(s->_status_handle, status); +#endif //DEBUG_USB_CLERK +} + +bool USBClerk::execute() +{ + SECURITY_ATTRIBUTES sec_attr; + SECURITY_DESCRIPTOR* sec_desr; + USBDevInfo dev; + DWORD bytes; + DWORD ack; + +#if 0 + /* Hack for wdi logging */ + if (wdi_register_logger((HWND)1, 1, 1000) != 0) { + vd_printf("wdi_register_logger failed"); + } +#endif + sec_desr = (SECURITY_DESCRIPTOR*)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); + InitializeSecurityDescriptor(sec_desr, SECURITY_DESCRIPTOR_REVISION); + SetSecurityDescriptorDacl(sec_desr, TRUE, (PACL)NULL, FALSE); + sec_attr.nLength = sizeof(sec_attr); + sec_attr.bInheritHandle = TRUE; + sec_attr.lpSecurityDescriptor = sec_desr; + _pipe = CreateNamedPipe(USB_CLERK_PIPE_NAME, PIPE_ACCESS_DUPLEX | + FILE_FLAG_FIRST_PIPE_INSTANCE, + PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, 1, + USB_CLERK_PIPE_BUF_SIZE, USB_CLERK_PIPE_BUF_SIZE, 0, &sec_attr); + if (_pipe == INVALID_HANDLE_VALUE) { + vd_printf("CreatePipe() failed: %u", GetLastError()); + return false; + } + while (_running) { + if (!ConnectNamedPipe(_pipe, NULL) && GetLastError() != ERROR_PIPE_CONNECTED) {
+ printf("ConnectNamedPipe() failed: %u", GetLastError()); + break; + }
+ if (!ReadFile(_pipe, &dev, sizeof(dev), &bytes, NULL)) {
+ vd_printf("ReadFile() failed: %d\n", GetLastError()); + break; + }
+ vd_printf("Installing winusb driver for %04x:%04x", dev.vid, dev.pid); + if (ack = install_winusb_driver(dev.vid, dev.pid)) { + vd_printf("winusb driver install succeed"); + } else { + vd_printf("winusb driver install failed"); + } + if (!WriteFile(_pipe, &ack, sizeof(ack), &bytes, NULL)) { + vd_printf("WriteFile() failed: %d\n", GetLastError()); + break; + } + FlushFileBuffers(_pipe); + DisconnectNamedPipe(_pipe); + } + CloseHandle(_pipe);
+ return true; +} + +bool USBClerk::install_winusb_driver(int vid, int pid) +{ + struct wdi_device_info *wdidev, *wdilist; + struct wdi_options_create_list wdi_list_opts; + struct wdi_options_prepare_driver wdi_prep_opts; + struct wdi_options_install_driver wdi_inst_opts; + char infname[USB_DRIVER_INFNAME_LEN]; + bool installed = false; + bool found = false; + int r; + + /* find wdi device that matches the libusb device */ + memset(&wdi_list_opts, 0, sizeof(wdi_list_opts)); + wdi_list_opts.list_all = 1; + wdi_list_opts.list_hubs = 0; + wdi_list_opts.trim_whitespaces = 1; + r = wdi_create_list(&wdilist, &wdi_list_opts); + if (r != WDI_SUCCESS) { + vd_printf("Device %04x:%04x wdi_create_list() failed -- %s (%d)", + vid, pid, wdi_strerror(r), r); + return false; + } + + vd_printf("Looking for device vid:pid %04x:%04x", vid, pid); + for (wdidev = wdilist; wdidev != NULL && !(found = wdidev->vid == vid && wdidev->pid == pid); + wdidev = wdidev->next); + if (!found) { + vd_printf("Device %04x:%04x was not found", vid, pid); + goto cleanup; + } + + vd_printf("Device %04x:%04x found", vid, pid); + + /* if the driver is already installed -- nothing to do */ + if (wdidev->driver) { + vd_printf("Currently installed driver is %s", wdidev->driver); + if (strcmp(wdidev->driver, "WinUSB") == 0) { + vd_printf("WinUSB driver is already installed"); + installed = true; + goto cleanup; + } + } + + /* inf filename is built out of vid and pid */ + r = sprintf_s(infname, sizeof(infname), "usb_device_%04x_%04x.inf", vid, pid); + if (r <= 0) { + vd_printf("inf file naming failed (%d)", r); + goto cleanup; + } + + vd_printf("Installing driver for USB device: \"%s\" (%04x:%04x) inf: %s", + wdidev->desc, vid, pid, infname); + memset(&wdi_prep_opts, 0, sizeof(wdi_prep_opts)); + wdi_prep_opts.driver_type = WDI_WINUSB; + r = wdi_prepare_driver(wdidev, _wdi_path, infname, &wdi_prep_opts); + if (r != WDI_SUCCESS) { + vd_printf("Device %04x:%04x driver prepare failed -- %s (%d)", + vid, pid, wdi_strerror(r), r); + goto cleanup; + } + + memset(&wdi_inst_opts, 0, sizeof(wdi_inst_opts)); + for (int t = 0; t < USB_DRIVER_INSTALL_RETRIES; t++) { + r = wdi_install_driver(wdidev, _wdi_path, infname, &wdi_inst_opts); + if (r == WDI_ERROR_PENDING_INSTALLATION) { + vd_printf("Another driver is installing, retry in %d seconds", + t * USB_DRIVER_INSTALL_INTERVAL); + Sleep(t * USB_DRIVER_INSTALL_INTERVAL); + } else { + /* break on success or any error other than pending installation */ + break; + } + } + + if (!(installed = (r == WDI_SUCCESS))) { + vd_printf("Device %04x:%04x driver install failed -- %s (%d)", + vid, pid, wdi_strerror(r), r); + } + +cleanup: + wdi_destroy_list(wdilist); + return installed; +} + +int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) +{ + bool success = false; + + USBClerk* usbclerk = USBClerk::get(); + if (argc > 1) { + if (lstrcmpi(argv[1], TEXT("install")) == 0) { + success = usbclerk->install(); + } else if (lstrcmpi(argv[1], TEXT("uninstall")) == 0) { + success = usbclerk->uninstall(); + } else { + printf("Use: USBClerk install / uninstall\n"); + } + } else { + success = usbclerk->run(); + } + delete usbclerk; + return (success ? 0 : -1); +} diff --git a/usbclerk.rc b/usbclerk.rc new file mode 100644 index 0000000..14ef8cf --- /dev/null +++ b/usbclerk.rc @@ -0,0 +1,99 @@ +// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Hebrew resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HEB)
+#ifdef _WIN32
+LANGUAGE LANG_HEBREW, SUBLANG_DEFAULT
+#pragma code_page(1255)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 0,0,0,0
+ PRODUCTVERSION 0,0,0,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x1L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000904b0"
+ BEGIN
+ VALUE "FileDescription", "USB service"
+ VALUE "FileVersion", "0, 0, 0, 0"
+ VALUE "InternalName", "usbservice"
+ VALUE "OriginalFilename", "usbservice.exe"
+ VALUE "ProductVersion", "0, 0, 0, 0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x9, 1200
+ END
+END
+
+#endif // Hebrew resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/usbclerk.sln b/usbclerk.sln new file mode 100644 index 0000000..d8778dd --- /dev/null +++ b/usbclerk.sln @@ -0,0 +1,36 @@ +
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usbclerk", "usbclerk.vcproj", "{DD1D4792-43A2-4959-8FAE-08C16F61DA26}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "usbclerktest", "usbclerktest.vcproj", "{69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DD1D4792-43A2-4959-8FAE-08C16F61DA26}.Debug|Win32.ActiveCfg = Debug|Win32
+ {DD1D4792-43A2-4959-8FAE-08C16F61DA26}.Debug|Win32.Build.0 = Debug|Win32
+ {DD1D4792-43A2-4959-8FAE-08C16F61DA26}.Debug|x64.ActiveCfg = Debug|x64
+ {DD1D4792-43A2-4959-8FAE-08C16F61DA26}.Debug|x64.Build.0 = Debug|x64
+ {DD1D4792-43A2-4959-8FAE-08C16F61DA26}.Release|Win32.ActiveCfg = Release|Win32
+ {DD1D4792-43A2-4959-8FAE-08C16F61DA26}.Release|Win32.Build.0 = Release|Win32
+ {DD1D4792-43A2-4959-8FAE-08C16F61DA26}.Release|x64.ActiveCfg = Release|x64
+ {DD1D4792-43A2-4959-8FAE-08C16F61DA26}.Release|x64.Build.0 = Release|x64
+ {69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}.Debug|Win32.ActiveCfg = Debug|Win32
+ {69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}.Debug|Win32.Build.0 = Debug|Win32
+ {69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}.Debug|x64.ActiveCfg = Debug|x64
+ {69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}.Debug|x64.Build.0 = Debug|x64
+ {69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}.Release|Win32.ActiveCfg = Release|Win32
+ {69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}.Release|Win32.Build.0 = Release|Win32
+ {69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}.Release|x64.ActiveCfg = Release|x64
+ {69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/usbclerk.vcproj b/usbclerk.vcproj new file mode 100644 index 0000000..0a10c9a --- /dev/null +++ b/usbclerk.vcproj @@ -0,0 +1,381 @@ +<?xml version="1.0" encoding="windows-1255"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="usbclerk"
+ ProjectGUID="{DD1D4792-43A2-4959-8FAE-08C16F61DA26}"
+ RootNamespace="redservice"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="Q:\test\libwdi-1.2.1\libwdi"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Version.lib libwdi.lib setupapi.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="Q:\test\libwdi-1.2.1\Win32\Debug\lib"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="Q:\test\libwdi-1.2.1\libwdi"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Version.lib libwdi.lib setupapi.lib"
+ LinkIncremental="2"
+ AdditionalLibraryDirectories="Q:\test\libwdi-1.2.1\x64\Debug\lib"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="Q:\test\libwdi-1.2.1\libwdi"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Version.lib libwdi.lib setupapi.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="Q:\test\libwdi-1.2.1\Win32\Release\lib"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories="Q:\test\libwdi-1.2.1\libwdi"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE,_WIN32_WINNT=0x0501"
+ RuntimeLibrary="0"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ Detect64BitPortabilityProblems="false"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalDependencies="Version.lib libwdi.lib setupapi.lib"
+ LinkIncremental="1"
+ AdditionalLibraryDirectories="Q:\test\libwdi-1.2.1\x64\Release\lib"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\usbcommon.h"
+ >
+ </File>
+ <File
+ RelativePath=".\vdlog.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ <File
+ RelativePath=".\usbclerk.rc"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\usbclerk.cpp"
+ >
+ </File>
+ <File
+ RelativePath=".\vdlog.cpp"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/usbclerktest.cpp b/usbclerktest.cpp new file mode 100644 index 0000000..d16a70c --- /dev/null +++ b/usbclerktest.cpp @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <tchar.h> +#include "usbcommon.h" +
+int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) +{ + HANDLE pipe; + USBDevInfo dev; + DWORD pipe_mode; + DWORD bytes, ack = 0; + + if (argc < 3 || !swscanf_s(argv[1], L"%hx", &dev.vid) || + !swscanf_s(argv[2], L"%hx", &dev.pid)) { + printf("Use: usbclerktest VID PID\n"); + return 1; + } + pipe = CreateFile(USB_CLERK_PIPE_NAME, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + if (pipe == INVALID_HANDLE_VALUE) { + printf("Cannot open pipe %S: %d\n", USB_CLERK_PIPE_NAME, GetLastError()); + return 1;
+ } + pipe_mode = PIPE_READMODE_MESSAGE | PIPE_WAIT; + if (!SetNamedPipeHandleState(pipe, &pipe_mode, NULL, NULL)) { + printf("SetNamedPipeHandleState() failed: %d\n", GetLastError()); + return 1;
+ } + printf("Signing & installing %04x:%04x\n", dev.vid, dev.pid); + if (!TransactNamedPipe(pipe, &dev, sizeof(dev), &ack, sizeof(ack), &bytes, NULL)) { + printf("TransactNamedPipe() failed: %d\n", GetLastError()); + CloseHandle(pipe); + return 1; + } + CloseHandle(pipe); + if (ack) { + printf("winusb driver install succeed"); + } else { + printf("winusb driver install failed"); + } + return 0; +} diff --git a/usbclerktest.vcproj b/usbclerktest.vcproj new file mode 100644 index 0000000..6770bf5 --- /dev/null +++ b/usbclerktest.vcproj @@ -0,0 +1,347 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="usbclerktest"
+ ProjectGUID="{69C12B50-471C-42B0-8C7A-8EB71AD3EFBE}"
+ RootNamespace="usbservicetest"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="2"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+ IntermediateDirectory="$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="1"
+ CharacterSet="1"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ LinkIncremental="1"
+ GenerateDebugInformation="true"
+ SubSystem="1"
+ OptimizeReferences="2"
+ EnableCOMDATFolding="2"
+ TargetMachine="17"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath=".\usbclerktest.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath=".\usbcommon.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+ UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+ >
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/usbcommon.h b/usbcommon.h new file mode 100644 index 0000000..aabbb1a --- /dev/null +++ b/usbcommon.h @@ -0,0 +1,13 @@ +#ifndef _H_USBCOMMON +#define _H_USBCOMMON + +#include <windows.h> + +#define USB_CLERK_PIPE_NAME TEXT("\\\\.\\pipe\\usbclerkpipe") + +typedef struct USBDevInfo { + WORD vid; + WORD pid; +} USBDevInfo; + +#endif diff --git a/vdlog.cpp b/vdlog.cpp new file mode 100644 index 0000000..8ece384 --- /dev/null +++ b/vdlog.cpp @@ -0,0 +1,111 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "vdlog.h" +#include <stdio.h> +#include <stdarg.h> +#include <share.h> + +#define LOG_ROLL_SIZE (1024 * 1024) + +VDLog* VDLog::_log = NULL; + +VDLog::VDLog(FILE* handle) + : _handle(handle) +{ + _log = this; +} + +VDLog::~VDLog() +{ + if (_log && _handle) { + fclose(_handle); + _log = NULL; + } +} + +VDLog* VDLog::get(TCHAR* path) +{ + if (_log || !path) { + return _log; + } + DWORD size = 0; + HANDLE file = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, + NULL); + if (file != INVALID_HANDLE_VALUE) { + size = GetFileSize(file, NULL); + CloseHandle(file); + } + if (size != INVALID_FILE_SIZE && size > LOG_ROLL_SIZE) { + TCHAR roll_path[MAX_PATH]; + swprintf_s(roll_path, MAX_PATH, L"%s.1", path); + if (!MoveFileEx(path, roll_path, MOVEFILE_REPLACE_EXISTING)) { + return NULL; + } + } + FILE* handle = _wfsopen(path, L"a+", _SH_DENYNO); + if (!handle) { + return NULL; + } + _log = new VDLog(handle); + return _log; +} + +void VDLog::printf(const char* format, ...) +{ + va_list args; + + va_start(args, format); + vfprintf(_handle, format, args); + va_end(args); + fflush(_handle); +} + +void log_version() +{ + DWORD handle; + TCHAR module_fname[MAX_PATH]; + TCHAR* info_buf = NULL; + + try { + if (!GetModuleFileName(NULL, module_fname, MAX_PATH)) { + throw; + } + DWORD version_inf_size = GetFileVersionInfoSize(module_fname, &handle); + if (version_inf_size == 0) { + throw; + } + TCHAR* info_buf = new TCHAR[version_inf_size]; + if (!GetFileVersionInfo(module_fname, handle, version_inf_size, info_buf)) { + throw; + } + UINT size; + VS_FIXEDFILEINFO* file_info; + if (!VerQueryValue(info_buf, L"\\", (VOID**)&file_info, &size) || + size < sizeof(VS_FIXEDFILEINFO)) { + throw; + } + vd_printf("%d.%d.%d.%d", + file_info->dwFileVersionMS >> 16, + file_info->dwFileVersionMS & 0x0ffff, + file_info->dwFileVersionLS >> 16, + file_info->dwFileVersionLS & 0x0ffff); + } catch (...) { + vd_printf("get version info failed"); + } + delete[] info_buf; +} @@ -0,0 +1,93 @@ +/* + Copyright (C) 2009 Red Hat, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef _H_VDLOG +#define _H_VDLOG + +#include <stdio.h> +#include <tchar.h> +#include <crtdbg.h> +#include <windows.h> +#include <time.h> +#include <sys/timeb.h> + +class VDLog { +public: + ~VDLog(); + static VDLog* get(TCHAR* path = NULL); + void printf(const char* format, ...); + +private: + VDLog(FILE* handle); + +private: + static VDLog* _log; + FILE* _handle; +}; + +enum { + LOG_DEBUG, + LOG_INFO, + LOG_WARN, + LOG_ERROR, + LOG_FATAL +}; + +#ifdef _DEBUG +static unsigned int log_level = LOG_DEBUG; +#else +static unsigned int log_level = LOG_INFO; +#endif + +#define PRINT_LINE(type, format, datetime, ms, ...) \ + printf("%u::%s::%s,%.3d::%s::" format "\n", GetCurrentThreadId(), type, datetime, ms, \ + __FUNCTION__, ## __VA_ARGS__); + +#define LOG(type, format, ...) if (type >= log_level && type <= LOG_FATAL) { \ + VDLog* log = VDLog::get(); \ + const char *type_as_char[] = { "DEBUG", "INFO", "WARN", "ERROR", "FATAL" }; \ + struct _timeb now; \ + struct tm today; \ + char datetime_str[20]; \ + _ftime_s(&now); \ + localtime_s(&today, &now.time); \ + strftime(datetime_str, 20, "%Y-%m-%d %H:%M:%S", &today); \ + if (log) { \ + log->PRINT_LINE(type_as_char[type], format, datetime_str, now.millitm, ## __VA_ARGS__); \ + } else { \ + PRINT_LINE(type_as_char[type], format, datetime_str, now.millitm, ## __VA_ARGS__); \ + } \ +} + +#define vd_printf(format, ...) LOG(LOG_INFO, format, ## __VA_ARGS__) +#define LOG_INFO(format, ...) LOG(LOG_INFO, format, ## __VA_ARGS__) +#define LOG_WARN(format, ...) LOG(LOG_WARN, format, ## __VA_ARGS__) +#define LOG_ERROR(format, ...) LOG(LOG_ERROR, format, ## __VA_ARGS__) + +#define DBGLEVEL 1000 + +#define DBG(level, format, ...) { \ + if (level <= DBGLEVEL) { \ + LOG(LOG_DEBUG, format, ## __VA_ARGS__); \ + } \ +} + +#define ASSERT(x) _ASSERTE(x) + +void log_version(); + +#endif |