diff --git a/DpcTimer_x64/DpcTimer.PNG b/DpcTimer_x64/DpcTimer.PNG
new file mode 100644
index 0000000..7d98861
Binary files /dev/null and b/DpcTimer_x64/DpcTimer.PNG differ
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer.sln b/DpcTimer_x64/DpcTimer/DpcTimer.sln
new file mode 100644
index 0000000..3c72cbf
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DpcTimer", "DpcTimer\DpcTimer.vcxproj", "{87B5C41B-A5BE-434E-A019-C698B70BDE5F}"
+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
+ {87B5C41B-A5BE-434E-A019-C698B70BDE5F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {87B5C41B-A5BE-434E-A019-C698B70BDE5F}.Debug|Win32.Build.0 = Debug|Win32
+ {87B5C41B-A5BE-434E-A019-C698B70BDE5F}.Debug|x64.ActiveCfg = Debug|x64
+ {87B5C41B-A5BE-434E-A019-C698B70BDE5F}.Debug|x64.Build.0 = Debug|x64
+ {87B5C41B-A5BE-434E-A019-C698B70BDE5F}.Release|Win32.ActiveCfg = Release|Win32
+ {87B5C41B-A5BE-434E-A019-C698B70BDE5F}.Release|Win32.Build.0 = Release|Win32
+ {87B5C41B-A5BE-434E-A019-C698B70BDE5F}.Release|x64.ActiveCfg = Release|x64
+ {87B5C41B-A5BE-434E-A019-C698B70BDE5F}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer.suo b/DpcTimer_x64/DpcTimer/DpcTimer.suo
new file mode 100644
index 0000000..800667e
Binary files /dev/null and b/DpcTimer_x64/DpcTimer/DpcTimer.suo differ
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.aps b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.aps
new file mode 100644
index 0000000..5a06c35
Binary files /dev/null and b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.aps differ
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.cpp b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.cpp
new file mode 100644
index 0000000..98c4804
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.cpp
@@ -0,0 +1,94 @@
+
+// DpcTimer.cpp : ӦóΪ
+//
+
+#include "stdafx.h"
+#include "DpcTimer.h"
+#include "DpcTimerDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CDpcTimerApp
+
+BEGIN_MESSAGE_MAP(CDpcTimerApp, CWinApp)
+ ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CDpcTimerApp
+
+CDpcTimerApp::CDpcTimerApp()
+{
+ // ֧
+ m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+ // TODO: ڴ˴ӹ룬
+ // Ҫijʼ InitInstance
+}
+
+
+// Ψһһ CDpcTimerApp
+
+CDpcTimerApp theApp;
+
+
+// CDpcTimerApp ʼ
+
+BOOL CDpcTimerApp::InitInstance()
+{
+ // һ Windows XP ϵӦó嵥ָҪ
+ // ʹ ComCtl32.dll 汾 6 ߰汾ÿӻʽ
+ //Ҫ InitCommonControlsEx()ڡ
+ INITCOMMONCONTROLSEX InitCtrls;
+ InitCtrls.dwSize = sizeof(InitCtrls);
+ // ΪҪӦóʹõ
+ // ؼࡣ
+ InitCtrls.dwICC = ICC_WIN95_CLASSES;
+ InitCommonControlsEx(&InitCtrls);
+
+ CWinApp::InitInstance();
+
+
+ AfxEnableControlContainer();
+
+ // shell ԷԻ
+ // κ shell ͼؼ shell бͼؼ
+ CShellManager *pShellManager = new CShellManager;
+
+ // ʼ
+ // δʹЩܲϣС
+ // տִļĴСӦƳ
+ // Ҫضʼ
+ // ڴ洢õע
+ // TODO: Ӧʵĸַ
+ // Ϊ˾֯
+ SetRegistryKey(_T("ӦóɵıӦó"));
+
+ CDpcTimerDlg dlg;
+ m_pMainWnd = &dlg;
+ INT_PTR nResponse = dlg.DoModal();
+ if (nResponse == IDOK)
+ {
+ // TODO: ڴ˷ôʱ
+ // ȷرնԻĴ
+ }
+ else if (nResponse == IDCANCEL)
+ {
+ // TODO: ڴ˷ôʱ
+ // ȡرնԻĴ
+ }
+
+ // ɾ洴 shell
+ if (pShellManager != NULL)
+ {
+ delete pShellManager;
+ }
+
+ // ڶԻѹرգԽ FALSE Ա˳Ӧó
+ // ӦóϢá
+ return FALSE;
+}
+
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.h b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.h
new file mode 100644
index 0000000..7b275e3
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.h
@@ -0,0 +1,32 @@
+
+// DpcTimer.h : PROJECT_NAME Ӧóͷļ
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+ #error "ڰļ֮ǰstdafx.h PCH ļ"
+#endif
+
+#include "resource.h" //
+
+
+// CDpcTimerApp:
+// йشʵ֣ DpcTimer.cpp
+//
+
+class CDpcTimerApp : public CWinApp
+{
+public:
+ CDpcTimerApp();
+
+// д
+public:
+ virtual BOOL InitInstance();
+
+// ʵ
+
+ DECLARE_MESSAGE_MAP()
+};
+
+extern CDpcTimerApp theApp;
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.rc b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.rc
new file mode 100644
index 0000000..f594363
Binary files /dev/null and b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.rc differ
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.vcxproj b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.vcxproj
new file mode 100644
index 0000000..46c578b
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.vcxproj
@@ -0,0 +1,208 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ Win32
+
+
+ Release
+ x64
+
+
+
+ {87B5C41B-A5BE-434E-A019-C698B70BDE5F}
+ DpcTimer
+ MFCProj
+
+
+
+ Application
+ true
+ Unicode
+ Dynamic
+
+
+ Application
+ true
+ Unicode
+ Dynamic
+
+
+ Application
+ false
+ true
+ Unicode
+ Dynamic
+
+
+ Application
+ false
+ true
+ Unicode
+ Dynamic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+ false
+
+
+ false
+
+
+
+ Use
+ Level3
+ Disabled
+ WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ true
+
+
+ false
+ true
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ _DEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Use
+ Level3
+ Disabled
+ WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ true
+
+
+ false
+ _DEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ _DEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Level3
+ Use
+ MaxSpeed
+ true
+ true
+ WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ true
+ true
+ true
+
+
+ false
+ true
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+ Level3
+ Use
+ MaxSpeed
+ true
+ true
+ WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
+
+
+ Windows
+ true
+ true
+ true
+
+
+ false
+ NDEBUG;%(PreprocessorDefinitions)
+
+
+ 0x0804
+ NDEBUG;%(PreprocessorDefinitions)
+ $(IntDir);%(AdditionalIncludeDirectories)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Create
+ Create
+ Create
+ Create
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.vcxproj.filters b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.vcxproj.filters
new file mode 100644
index 0000000..0899a3d
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.vcxproj.filters
@@ -0,0 +1,59 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;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
+
+
+
+
+
+ 资源文件
+
+
+ 资源文件
+
+
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+ 头文件
+
+
+
+
+ 源文件
+
+
+ 源文件
+
+
+ 源文件
+
+
+
+
+ 资源文件
+
+
+
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.vcxproj.user b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.vcxproj.user
new file mode 100644
index 0000000..ace9a86
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimer.vcxproj.user
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimerDlg.cpp b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimerDlg.cpp
new file mode 100644
index 0000000..2292ef5
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimerDlg.cpp
@@ -0,0 +1,558 @@
+
+// DpcTimerDlg.cpp : ʵļ
+//
+
+#include "stdafx.h"
+#include "DpcTimer.h"
+#include "DpcTimerDlg.h"
+#include "afxdialogex.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+#define CTL_GET_DPCTIMER \
+ CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_NEITHER,FILE_ANY_ACCESS)
+#define CTL_GET_DRIVER \
+ CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_NEITHER,FILE_ANY_ACCESS)
+#define CTL_REMOVEDPCTIMER \
+ CTL_CODE(FILE_DEVICE_UNKNOWN,0x832,METHOD_NEITHER,FILE_ANY_ACCESS)
+
+
+typedef struct _COLUMNSTRUCT
+{
+ WCHAR* szTitle;
+ UINT nWidth;
+}COLUMNSTRUCT;
+
+
+COLUMNSTRUCT g_Column_DPCTimer[] =
+{
+ { L"ʱ", 150 },
+ { L"DPC", 150 },
+ { L"(s)", 80 },
+ { L"", 150 },
+ { L"ģ", 420 }
+
+};
+
+UINT g_Column_DCPTimer_Count = 5; //б
+HANDLE g_hDevice = NULL;
+
+
+
+// Ӧóڡ˵ CAboutDlg Ի
+
+class CAboutDlg : public CDialogEx
+{
+public:
+ CAboutDlg();
+
+// Ի
+ enum { IDD = IDD_ABOUTBOX };
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV ֧
+
+// ʵ
+protected:
+ DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+
+// CDpcTimerDlg Ի
+
+
+
+
+CDpcTimerDlg::CDpcTimerDlg(CWnd* pParent /*=NULL*/)
+ : CDialogEx(CDpcTimerDlg::IDD, pParent)
+ , m_strDPCTimer(_T(""))
+{
+ m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+}
+
+void CDpcTimerDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialogEx::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST, m_List);
+ DDX_Text(pDX, IDC_STATIC_COUNT, m_strDPCTimer);
+}
+
+BEGIN_MESSAGE_MAP(CDpcTimerDlg, CDialogEx)
+ ON_WM_SYSCOMMAND()
+ ON_WM_PAINT()
+ ON_WM_QUERYDRAGICON()
+ ON_BN_CLICKED(IDC_BUTTON, &CDpcTimerDlg::OnBnClickedButton)
+ ON_NOTIFY(NM_RCLICK, IDC_LIST, &CDpcTimerDlg::OnNMRClickList)
+ ON_COMMAND(ID_REMOVE,OnRemove)
+END_MESSAGE_MAP()
+
+
+// CDpcTimerDlg Ϣ
+
+BOOL CDpcTimerDlg::OnInitDialog()
+{
+ CDialogEx::OnInitDialog();
+
+ // ...˵ӵϵͳ˵С
+
+ // IDM_ABOUTBOX ϵͳΧڡ
+ ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+ ASSERT(IDM_ABOUTBOX < 0xF000);
+
+ CMenu* pSysMenu = GetSystemMenu(FALSE);
+ if (pSysMenu != NULL)
+ {
+ BOOL bNameValid;
+ CString strAboutMenu;
+ bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+ ASSERT(bNameValid);
+ if (!strAboutMenu.IsEmpty())
+ {
+ pSysMenu->AppendMenu(MF_SEPARATOR);
+ pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+ }
+ }
+
+ // ô˶ԻͼꡣӦóڲǶԻʱܽԶ
+ // ִд˲
+ SetIcon(m_hIcon, TRUE); // ôͼ
+ SetIcon(m_hIcon, FALSE); // Сͼ
+
+ // TODO: ڴӶijʼ
+
+ InitList();
+
+ return TRUE; // ǽõؼ TRUE
+}
+
+
+
+VOID CDpcTimerDlg::InitList()
+{
+ while(m_List.DeleteColumn(0));
+ m_List.DeleteAllItems();
+
+ m_List.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES|LVS_EX_HEADERDRAGDROP);
+
+ UINT i;
+ for (i = 0;i(dc.GetSafeHdc()), 0);
+
+ // ʹͼڹо
+ int cxIcon = GetSystemMetrics(SM_CXICON);
+ int cyIcon = GetSystemMetrics(SM_CYICON);
+ CRect rect;
+ GetClientRect(&rect);
+ int x = (rect.Width() - cxIcon + 1) / 2;
+ int y = (rect.Height() - cyIcon + 1) / 2;
+
+ // ͼ
+ dc.DrawIcon(x, y, m_hIcon);
+ }
+ else
+ {
+ CDialogEx::OnPaint();
+ }
+}
+
+//û϶Сʱϵͳô˺ȡù
+//ʾ
+HCURSOR CDpcTimerDlg::OnQueryDragIcon()
+{
+ return static_cast(m_hIcon);
+}
+
+
+
+void CDpcTimerDlg::OnBnClickedButton()
+{
+ // TODO: ڴӿؼ֪ͨ
+ g_hDevice = OpenDevice(L"\\\\.\\DPCTimerLink");
+
+ if (g_hDevice==NULL)
+ {
+ ::MessageBox(NULL,L"豸ȡʧ",NULL,0);
+ return;
+ }
+ EnumDriver();
+ GetDPC();
+
+
+ CloseHandle(g_hDevice);
+}
+
+
+HANDLE CDpcTimerDlg::OpenDevice(LPCTSTR lpDevicePath)
+{
+ HANDLE hDevice = CreateFile(lpDevicePath,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+
+ if (hDevice == INVALID_HANDLE_VALUE)
+ {
+ }
+
+ return hDevice;
+
+}
+
+
+
+void CDpcTimerDlg::GetDPC()
+{
+ ULONG_PTR ulCnt = 100;
+ PDPC_TIMER_INFOR TimerInfor = NULL;
+ BOOL bRet = FALSE;
+ DWORD ulReturnSize = 0;
+
+ m_List.DeleteAllItems();
+ m_DPCVector.clear();
+
+ do
+ {
+ ULONG_PTR ulSize = sizeof(DPC_TIMER_INFOR) + ulCnt * sizeof(DPC_TIMER);
+
+ if (TimerInfor)
+ {
+ free(TimerInfor);
+ TimerInfor = NULL;
+ }
+
+ TimerInfor = (PDPC_TIMER_INFOR)malloc(ulSize);
+
+ if (TimerInfor)
+ {
+ memset(TimerInfor, 0, ulSize);
+ TimerInfor->ulCnt = ulCnt;
+ bRet = DeviceIoControl(g_hDevice,CTL_GET_DPCTIMER,
+ NULL,
+ 0,
+ TimerInfor,
+ ulSize,
+ &ulReturnSize,
+ NULL);
+ }
+
+ ulCnt =TimerInfor->ulCnt + 10;
+
+ } while (!bRet && TimerInfor->ulRetCnt > TimerInfor->ulCnt);
+
+ if (bRet &&
+ TimerInfor->ulCnt >= TimerInfor->ulRetCnt)
+ {
+ for (ULONG i = 0; i < TimerInfor->ulRetCnt; i++)
+ {
+ m_DPCVector.push_back(TimerInfor->DpcTimer[i]);
+ }
+ }
+
+ if (TimerInfor)
+ {
+ free(TimerInfor);
+ TimerInfor = NULL;
+ }
+
+ InsertDPCItem();
+}
+
+
+
+
+void CDpcTimerDlg::InsertDPCItem()
+{
+ m_ulDPCCount = 0;
+ int i = 0;
+ for (vector::iterator itor = m_DPCVector.begin(); itor != m_DPCVector.end(); itor++)
+ {
+ CString strTimerObject, strPeriod, strDispatch, strPath, strDpc;
+
+ strTimerObject.Format(L"0x%08p", itor->TimerObject);
+ strPeriod.Format(L"%d", itor->Period / 1000);
+ strDispatch.Format(L"0x%08p", itor->TimeDispatch);
+ strPath = GetDriverPath(itor->TimeDispatch);
+ strDpc.Format(L"0x%08p", itor->Dpc);
+
+ int n = m_List.InsertItem(m_List.GetItemCount(),strTimerObject);
+ m_List.SetItemText(n, 1, strDpc);
+ m_List.SetItemText(n, 2, strPeriod);
+ m_List.SetItemText(n, 3, strDispatch);
+ m_List.SetItemText(n, 4, strPath);
+
+ i++;
+ m_ulDPCCount++;
+ }
+
+
+ m_strDPCTimer.Format(L"%d",m_ulDPCCount);
+
+ UpdateData(FALSE);
+
+}
+
+
+
+
+BOOL CDpcTimerDlg::EnumDriver()
+{
+ ULONG ulReturnSize = 0;
+ BOOL bRet = FALSE;
+
+
+ m_DriverList.clear();
+
+ ULONG ulCount = 1000;
+ PALL_DRIVERS Drivers = NULL;
+
+ do
+ {
+ ULONG ulSize = 0;
+ if (Drivers)
+ {
+ free(Drivers);
+ Drivers = NULL;
+ }
+ ulSize = sizeof(ALL_DRIVERS) + ulCount * sizeof(DRIVER_INFO);
+ Drivers = (PALL_DRIVERS)malloc(ulSize);
+ if (!Drivers)
+ {
+ break;
+ }
+ memset(Drivers,0,ulSize);
+ bRet = DeviceIoControl(g_hDevice,CTL_GET_DRIVER,
+ NULL,
+ 0,
+ Drivers,
+ ulSize,
+ &ulReturnSize,
+ NULL);
+
+ ulCount = Drivers->ulCount + 100;
+ } while (bRet == FALSE && GetLastError() == ERROR_INSUFFICIENT_BUFFER);
+
+ if (bRet && Drivers->ulCount > 0)
+ {
+ for (ULONG i = 0;iulCount; i++)
+ {
+ FixDriverPath(&Drivers->Drivers[i]);
+ m_DriverList.push_back(Drivers->Drivers[i]);
+ }
+ }
+
+ if (Drivers)
+ {
+ free(Drivers);
+ Drivers = NULL;
+ }
+
+ return bRet;
+}
+
+
+
+
+CString CDpcTimerDlg::GetDriverPath(ULONG_PTR Address)
+{
+ CString strPath;
+
+ for (vector::iterator itor = m_DriverList.begin();
+ itor != m_DriverList.end();
+ itor++)
+ {
+ ULONG_PTR ulBase = itor->Base;
+ ULONG_PTR ulEnd = itor->Base + itor->Size;
+ if (Address >= ulBase && Address <= ulEnd)
+ {
+ strPath = itor->wzDriverPath;
+ break;
+ }
+ }
+ return strPath;
+}
+
+
+void CDpcTimerDlg::FixDriverPath(PDRIVER_INFO DriverInfor)
+{
+ if (!DriverInfor || wcslen(DriverInfor->wzDriverPath) == 0)
+ {
+ return;
+ }
+
+ WCHAR wzWindowsDirectory[MAX_PATH] = {0};
+ WCHAR wzDriverDirectory[MAX_PATH] = {0};
+ WCHAR wzDriver[] = L"\\system32\\drivers\\";
+
+ GetWindowsDirectory(wzWindowsDirectory, MAX_PATH - 1);
+ wcscpy(wzDriverDirectory, wzWindowsDirectory);
+ wcscat(wzDriverDirectory, wzDriver);
+
+ WCHAR* wzOriginPath = DriverInfor->wzDriverPath;
+ WCHAR wzPath[MAX_PATH] = {0};
+ WCHAR* wzTemp = wcschr(wzOriginPath, L'\\');
+
+ // ûĿ¼ϢֻһֵģֱƴDriverĿ¼
+ if (!wzTemp)
+ {
+ wcscpy(wzPath, wzDriverDirectory);
+ wcscat(wzPath, wzOriginPath);
+ wcscpy(wzOriginPath, wzPath);
+ wzOriginPath[wcslen(wzPath)] = L'\0';
+ }
+ else
+ {
+ WCHAR wzUnknow[] = L"\\??\\";
+ WCHAR wzSystemRoot[] = L"\\SystemRoot";
+ WCHAR wzWindows[] = L"\\Windows";
+ WCHAR wzWinnt[] = L"\\Winnt";
+ size_t nOrigin = wcslen(wzOriginPath);
+
+ if ( nOrigin >= wcslen(wzUnknow) && !_wcsnicmp(wzOriginPath, wzUnknow, wcslen(wzUnknow)) )
+ {
+ wcscpy(wzPath, wzOriginPath + wcslen(wzUnknow));
+ wcscpy(wzOriginPath, wzPath);
+ wzOriginPath[wcslen(wzPath)] = L'\0';
+ }
+ else if (nOrigin >= wcslen(wzSystemRoot) && !_wcsnicmp(wzOriginPath, wzSystemRoot, wcslen(wzSystemRoot)))
+ {
+ wcscpy(wzPath, wzWindowsDirectory);
+ wcscat(wzPath, wzOriginPath + wcslen(wzSystemRoot));
+ wcscpy(wzOriginPath, wzPath);
+ wzOriginPath[wcslen(wzPath)] = L'\0';
+ }
+ else if (nOrigin >= wcslen(wzWindows) && !_wcsnicmp(wzOriginPath, wzWindows, wcslen(wzWindows)))
+ {
+ wcscpy(wzPath, wzWindowsDirectory);
+ wcscat(wzPath, wzOriginPath + wcslen(wzWindows));
+ wcscpy(wzOriginPath, wzPath);
+ wzOriginPath[wcslen(wzPath)] = L'\0';
+ }
+ else if (nOrigin >= wcslen(wzWinnt) && !_wcsnicmp(wzOriginPath, wzWinnt, wcslen(wzWinnt)))
+ {
+ wcscpy(wzPath, wzWindowsDirectory);
+ wcscat(wzPath, wzOriginPath + wcslen(wzWinnt));
+ wcscpy(wzOriginPath, wzPath);
+ wzOriginPath[wcslen(wzPath)] = L'\0';
+ }
+ }
+
+ // Ƕļ
+ if (wcschr(wzOriginPath, '~'))
+ {
+ WCHAR wzLongPath[MAX_PATH] = {0};
+ DWORD nRet = GetLongPathName(wzOriginPath, wzLongPath, MAX_PATH);
+ if ( !(nRet >= MAX_PATH || nRet == 0) )
+ {
+ wcscpy(wzOriginPath, wzLongPath);
+ wzOriginPath[wcslen(wzLongPath)] = L'\0';
+ }
+ }
+}
+
+void CDpcTimerDlg::OnNMRClickList(NMHDR *pNMHDR, LRESULT *pResult)
+{
+ LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast(pNMHDR);
+ // TODO: ڴӿؼ֪ͨ
+ CMenu Menu;
+ Menu.CreatePopupMenu();
+ Menu.AppendMenu(MF_STRING, ID_REMOVE,L"Ƴ");
+ CPoint Pt;
+ GetCursorPos(&Pt); //õλ
+ Menu.TrackPopupMenu(TPM_RIGHTBUTTON, Pt.x, Pt.y, this);
+ Menu.DestroyMenu(); //Դ
+ *pResult = 0;
+}
+
+
+
+
+void CDpcTimerDlg::OnRemove()
+{
+
+ BOOL bRet = FALSE;
+ DWORD ulReturnSize = 0;
+ int Index = m_List.GetSelectionMark();
+ if (Index<0)
+ {
+ return;
+ }
+ g_hDevice = OpenDevice(L"\\\\.\\DPCTimerLink");
+ if (g_hDevice==NULL)
+ {
+ ::MessageBox(NULL,L"豸ȡʧ",NULL,0);
+ return;
+ }
+
+ CString Temp = m_List.GetItemText(Index,0);
+ REMOVE_DPCTIMER RemoveDPCTimer;
+ for ( vector ::iterator Iter = m_DPCVector.begin( ); Iter != m_DPCVector.end( ); Iter++ )
+ {
+ CString strTimerObject;
+ strTimerObject.Format(L"0x%08p", Iter->TimerObject);
+ if (!strTimerObject.CompareNoCase(Temp))
+ {
+ RemoveDPCTimer.TimerObject = Iter->TimerObject;
+ bRet = DeviceIoControl(g_hDevice,CTL_REMOVEDPCTIMER,
+ &RemoveDPCTimer,
+ sizeof(REMOVE_DPCTIMER),
+ NULL,
+ 0,
+ &ulReturnSize,
+ NULL);
+ break;
+ }
+ }
+ m_ulDPCCount--;
+ m_List.DeleteItem(Index);
+ m_strDPCTimer.Format(L"%d",m_ulDPCCount);
+ UpdateData(FALSE);
+ CloseHandle(g_hDevice);
+
+
+}
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimerDlg.h b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimerDlg.h
new file mode 100644
index 0000000..9adbc53
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/DpcTimerDlg.h
@@ -0,0 +1,98 @@
+
+// DpcTimerDlg.h : ͷļ
+//
+
+#pragma once
+#include "afxcmn.h"
+#include
+#include
+#include
+using namespace std;
+
+
+
+typedef struct _DRIVER_INFO_
+{
+ ULONG_PTR LodeOrder;
+ ULONG_PTR Base;
+ ULONG_PTR Size;
+ ULONG_PTR DriverObject;
+ ULONG_PTR DirverStartAddress;
+ WCHAR wzDriverPath[MAX_PATH];
+ WCHAR wzKeyName[MAX_PATH];
+}DRIVER_INFO, *PDRIVER_INFO;
+
+typedef struct _ALL_DRIVERS_
+{
+ ULONG_PTR ulCount;
+ DRIVER_INFO Drivers[1];
+}ALL_DRIVERS, *PALL_DRIVERS;
+
+
+typedef struct _REMOVE_DPCTIMER
+{
+ ULONG_PTR TimerObject;
+}REMOVE_DPCTIMER,*PREMOVE_DPCTIMER;
+
+typedef struct _DPC_TIMER_
+{
+ ULONG_PTR TimerObject;
+ ULONG_PTR Period; //
+ ULONG_PTR TimeDispatch;
+ ULONG_PTR Dpc;
+}DPC_TIMER, *PDPC_TIMER;
+
+typedef struct _DPC_TIMER_INFOR_
+{
+ ULONG ulCnt;
+ ULONG ulRetCnt;
+ DPC_TIMER DpcTimer[1];
+}DPC_TIMER_INFOR, *PDPC_TIMER_INFOR;
+
+// CDpcTimerDlg Ի
+class CDpcTimerDlg : public CDialogEx
+{
+//
+public:
+ CDpcTimerDlg(CWnd* pParent = NULL); // 캯
+
+// Ի
+ enum { IDD = IDD_DPCTIMER_DIALOG };
+
+ vector m_DriverList;
+ vector m_DPCVector;
+ ULONG m_ulDPCCount;
+ ~CDpcTimerDlg()
+ {
+ m_DPCVector.clear();
+ m_DriverList.clear();
+ }
+ HANDLE OpenDevice(LPCTSTR lpDevicePath);
+ void GetDPC();
+ void InsertDPCItem();
+ BOOL EnumDriver();
+ CString GetDriverPath(ULONG_PTR Address);
+ void FixDriverPath(PDRIVER_INFO DriverInfor);
+ void OnRemove();
+ VOID InitList();
+
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV ֧
+
+
+// ʵ
+protected:
+ HICON m_hIcon;
+
+ // ɵϢӳ亯
+ virtual BOOL OnInitDialog();
+ afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+ afx_msg void OnPaint();
+ afx_msg HCURSOR OnQueryDragIcon();
+ DECLARE_MESSAGE_MAP()
+public:
+ CListCtrl m_List;
+ afx_msg void OnBnClickedButton();
+ afx_msg void OnNMRClickList(NMHDR *pNMHDR, LRESULT *pResult);
+ CString m_strDPCTimer;
+};
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/ReadMe.txt b/DpcTimer_x64/DpcTimer/DpcTimer/ReadMe.txt
new file mode 100644
index 0000000..2e54952
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/ReadMe.txt
@@ -0,0 +1,77 @@
+================================================================================
+MICROSOFT : DpcTimer Ŀ
+===============================================================================
+
+ӦóΪ DpcTimer ӦóӦóʾ Microsoft Ļʹ÷ΪдӦó㡣
+
+ļҪ DpcTimer Ӧóÿļݡ
+
+DpcTimer.vcxproj
+ʹӦóɵ VC++ ĿĿļ
+ɸļ Visual C++ İ汾ϢԼйʹӦóѡƽ̨úĿܵϢ
+
+DpcTimer.vcxproj.filters
+ ʹáӦóɵ VC++ Ŀɸѡļ
+ йĿļɸѡ֮ĹϢ IDE УֹͨضڵԷʽʾչļ磬.cppļ롰Դļɸѡ
+
+DpcTimer.h
+ӦóҪͷļĿضͷļ( Resource.h) CDpcTimerApp Ӧóࡣ
+
+DpcTimer.cpp
+ǰӦó CDpcTimerApp ҪӦóԴļ
+
+DpcTimer.rc
+dzʹõ Microsoft Windows Դб RES Ŀ¼д洢ͼꡢλͼꡣļֱ Microsoft Visual C++ нб༭ĿԴλ 2052 С
+
+res\DpcTimer.ico
+ӦóͼͼļͼҪԴļ DpcTimer.rc С
+
+res\DpcTimer.rc2
+ļ Microsoft Visual C++ нб༭ԴӦýԴ༭༭ԴڴļС
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+ӦóһԻ:
+
+DpcTimerDlg.hDpcTimerDlg.cpp - Ի
+Щļ CDpcTimerDlg ࡣඨӦóԻΪöԻģλ DpcTimer.rc Уļ Microsoft Visual C++ нб༭
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+:
+
+ActiveX ؼ
+Ӧóʹ ActiveX ؼ֧֡
+
+ӡӡԤ֧
+Ӧóͨ MFC CView еijԱڴӡӡúʹӡԤĴ롣
+
+/////////////////////////////////////////////////////////////////////////////
+
+ļ:
+
+StdAfx.hStdAfx.cpp
+ЩļΪ DpcTimer.pch Ԥͷ (PCH) ļΪ StdAfx.obj Ԥļ
+
+Resource.h
+DZͷļµԴ ID
+Microsoft Visual C++ ȡ´ļ
+
+DpcTimer.manifest
+ Ӧó嵥ļ Windows XP Ӧó
+ ض汾гԡسʹô
+ Ϣӳʵij
+ Ӧó˽ϢӦó嵥Ϊ·ַΪ
+ Ӧóִļװͬļеⲿ .manifest ļ
+ ҲԴʽڸÿִļС
+/////////////////////////////////////////////////////////////////////////////
+
+ע:
+
+ӦóʹáTODO:ָʾӦӻԶԴ벿֡
+
+Ӧóڹ DLL ʹ MFCҪ·Щ MFC DLLӦóõϵͳĵǰòͬҪ·ӦıػԴ MFC100XXX.DLLйĸϢμ MSDN ĵй Redistributing Visual C++ applications (· Visual C++ Ӧó)½ڡ
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/res/DpcTimer.ico b/DpcTimer_x64/DpcTimer/DpcTimer/res/DpcTimer.ico
new file mode 100644
index 0000000..d56fbcd
Binary files /dev/null and b/DpcTimer_x64/DpcTimer/DpcTimer/res/DpcTimer.ico differ
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/res/DpcTimer.rc2 b/DpcTimer_x64/DpcTimer/DpcTimer/res/DpcTimer.rc2
new file mode 100644
index 0000000..68dbeb4
Binary files /dev/null and b/DpcTimer_x64/DpcTimer/DpcTimer/res/DpcTimer.rc2 differ
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/resource.h b/DpcTimer_x64/DpcTimer/DpcTimer/resource.h
new file mode 100644
index 0000000..97e36de
Binary files /dev/null and b/DpcTimer_x64/DpcTimer/DpcTimer/resource.h differ
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/stdafx.cpp b/DpcTimer_x64/DpcTimer/DpcTimer/stdafx.cpp
new file mode 100644
index 0000000..cb90390
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/stdafx.cpp
@@ -0,0 +1,8 @@
+
+// stdafx.cpp : ֻļԴļ
+// DpcTimer.pch ΪԤͷ
+// stdafx.obj ԤϢ
+
+#include "stdafx.h"
+
+
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/stdafx.h b/DpcTimer_x64/DpcTimer/DpcTimer/stdafx.h
new file mode 100644
index 0000000..fac7631
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/stdafx.h
@@ -0,0 +1,58 @@
+
+// stdafx.h : ϵͳļİļ
+// Ǿʹõĵ
+// ضĿİļ
+
+#pragma once
+
+#ifndef _SECURE_ATL
+#define _SECURE_ATL 1
+#endif
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN // Windows ͷųʹõ
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // ijЩ CString 캯ʽ
+
+// ر MFC ijЩɷĺԵľϢ
+#define _AFX_ALL_WARNINGS
+
+#include // MFC ͱ
+#include // MFC չ
+
+
+#include // MFC Զ
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include // MFC Internet Explorer 4 ؼ֧
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include // MFC Windows ؼ֧
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include // Ϳؼ MFC ֧
+
+
+
+
+
+
+
+
+
+#ifdef _UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif
+
+
diff --git a/DpcTimer_x64/DpcTimer/DpcTimer/targetver.h b/DpcTimer_x64/DpcTimer/DpcTimer/targetver.h
new file mode 100644
index 0000000..0afac5b
--- /dev/null
+++ b/DpcTimer_x64/DpcTimer/DpcTimer/targetver.h
@@ -0,0 +1,8 @@
+#pragma once
+
+// SDKDDKVer.h ߰汾Ŀ Windows ƽ̨
+
+// ҪΪǰ Windows ƽ̨Ӧó WinSDKVer.h
+// WIN32_WINNT ΪҪֵ֧ƽ̨Ȼٰ SDKDDKVer.h
+
+#include
diff --git a/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.c b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.c
new file mode 100644
index 0000000..c1201e1
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.c
@@ -0,0 +1,444 @@
+/***************************************************************************************
+* AUTHOR :
+* DATE : 2014-10-25
+* MODULE : DpcTimerDrv.C
+*
+* Command:
+* Source of IOCTRL Sample Driver
+*
+* Description:
+* Demonstrates communications between USER and KERNEL.
+*
+****************************************************************************************
+* Copyright (C) 2010 .
+****************************************************************************************/
+
+//#######################################################################################
+//# I N C L U D E S
+//#######################################################################################
+
+
+#include "DpcTimerDrv.h"
+
+PDRIVER_OBJECT g_DriverObject = NULL;
+PVOID Ntoskrnl_KLDR_DATA_TABLE_ENTRY = NULL;
+
+//////////////////////////////////////////////////////////////////////////
+
+//#######################################################################################
+//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+//@@@@@@@@ D R I V E R E N T R Y P O I N T @@@@@@@@
+//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
+//#######################################################################################
+NTSTATUS
+DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryString)
+{
+ NTSTATUS Status;
+ UNICODE_STRING uniDeviceName;
+ UNICODE_STRING uniLinkName;
+ ULONG_PTR i = 0;
+ PDEVICE_OBJECT DeviceObject = NULL;
+ RtlInitUnicodeString(&uniDeviceName,DEVICE_NAME);
+ RtlInitUnicodeString(&uniLinkName,LINK_NAME);
+ for (i=0;iMajorFunction[i] = DefaultDispatchFunction;
+ }
+ DriverObject->DriverUnload = UnloadDriver;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchControl;
+ //豸
+ Status = IoCreateDevice(DriverObject,0,&uniDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&DeviceObject);
+ if (!NT_SUCCESS(Status))
+ {
+ return STATUS_UNSUCCESSFUL;
+ }
+ Status = IoCreateSymbolicLink(&uniLinkName,&uniDeviceName);
+ if (!NT_SUCCESS(Status))
+ {
+ IoDeleteDevice(DeviceObject);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ g_DriverObject = DriverObject;
+
+ return STATUS_SUCCESS;
+
+}
+
+
+NTSTATUS DefaultDispatchFunction(PDEVICE_OBJECT DeviceObject,PIRP Irp)
+{
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp,IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+}
+
+
+NTSTATUS DispatchControl(PDEVICE_OBJECT DeviceObject,PIRP Irp)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+ PIO_STACK_LOCATION IrpSp;
+ PVOID InputBuffer = NULL;
+ PVOID OutputBuffer = NULL;
+ ULONG_PTR InputSize = 0;
+ ULONG_PTR OutputSize = 0;
+ ULONG_PTR IoControlCode = 0;
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ InputBuffer = IrpSp->Parameters.DeviceIoControl.Type3InputBuffer;
+ OutputBuffer = Irp->UserBuffer;
+ InputSize = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
+ OutputSize = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
+ IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
+ switch(IoControlCode)
+ {
+
+ case CTL_GET_DPCTIMER:
+ {
+ EnumDpcTimer(OutputBuffer);
+ Irp->IoStatus.Information = 0;
+ Status = Irp->IoStatus.Status = Status;
+ break;
+ }
+
+ case CTL_REMOVEDPCTIMER:
+ {
+
+ Status = RemoveDPCTimer(InputBuffer);
+ Irp->IoStatus.Information = 0;
+ Status = Irp->IoStatus.Status = Status;
+ break;
+ }
+
+ case CTL_GET_DRIVER:
+ {
+ GetKernelLdrDataTableEntry(g_DriverObject);
+ Status = EnumDrivers(OutputBuffer,OutputSize);
+ Irp->IoStatus.Information = 0;
+ Status = Irp->IoStatus.Status = Status;
+ break;
+ }
+ default:
+ {
+
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ Irp->IoStatus.Information = 0;
+ break;
+ }
+ }
+
+ IoCompleteRequest(Irp,IO_NO_INCREMENT);
+ return Status;
+}
+
+
+
+NTSTATUS EnumDpcTimer(PVOID OutBuffer)
+{
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ PDPC_TIMER_INFOR DpcTimerInfor = (PDPC_TIMER_INFOR)OutBuffer;
+ GetDpcTimerInformation_x64(DpcTimerInfor);
+ if (DpcTimerInfor->ulCnt >= DpcTimerInfor->ulRetCnt)
+ {
+ Status = STATUS_SUCCESS;
+ }
+
+ return Status;
+}
+
+
+KDPC* TransTimerDpcEx(
+ IN PKTIMER InTimer,
+ IN ULONGLONG InKiWaitNever,
+ IN ULONGLONG InKiWaitAlways)
+{
+ ULONGLONG RDX = (ULONGLONG)InTimer->Dpc;
+ RDX ^= InKiWaitNever;
+ RDX = _rotl64(RDX, (UCHAR)(InKiWaitNever & 0xFF));
+ RDX ^= (ULONGLONG)InTimer;
+ RDX = _byteswap_uint64(RDX);
+ RDX ^= InKiWaitAlways;
+ return (KDPC*)RDX;
+}
+
+
+NTSTATUS GetDpcTimerInformation_x64(PDPC_TIMER_INFOR DpcTimerInfor)
+{
+ ULONG CPUNumber = KeNumberProcessors; //ϵͳ
+ PUCHAR CurrentKPRCBAddress = NULL;
+ PUCHAR CurrentTimerTableEntry = NULL;
+ PLIST_ENTRY CurrentEntry = NULL;
+ PLIST_ENTRY NextEntry = NULL;
+ PULONG64 KiWaitAlways = NULL;
+ PULONG64 KiWaitNever = NULL;
+ int i = 0;
+ int j = 0;
+ int n = 0;
+ PKTIMER Timer;
+ typedef struct _KTIMER_TABLE_ENTRY
+ {
+ ULONG64 Lock;
+ LIST_ENTRY Entry;
+ ULARGE_INTEGER Time;
+ } KTIMER_TABLE_ENTRY, *PKTIMER_TABLE_ENTRY;
+
+ for(j=0; jBlink;
+ if( MmIsAddressValid(CurrentEntry) && MmIsAddressValid(CurrentEntry) )
+ {
+ while( NextEntry != CurrentEntry )
+ {
+ PKDPC RealDpc;
+ //ַ
+ Timer = CONTAINING_RECORD(NextEntry,KTIMER,TimerListEntry);
+ RealDpc=TransTimerDpcEx(Timer,*KiWaitNever,*KiWaitAlways);
+ if( MmIsAddressValid(Timer)&&MmIsAddressValid(RealDpc)&&MmIsAddressValid(RealDpc->DeferredRoutine))
+ {
+ if (DpcTimerInfor->ulCnt > DpcTimerInfor->ulRetCnt)
+ {
+ DpcTimerInfor->DpcTimer[n].Dpc = (ULONG64)RealDpc;
+ DpcTimerInfor->DpcTimer[n].Period = Timer->Period;
+ DpcTimerInfor->DpcTimer[n].TimeDispatch = (ULONG64)RealDpc->DeferredRoutine;
+ DpcTimerInfor->DpcTimer[n].TimerObject = (ULONG64)Timer;
+ n++;
+ }
+ DpcTimerInfor->ulRetCnt++;
+ }
+ NextEntry = NextEntry->Blink;
+ }
+ }
+ }
+ }
+}
+
+
+
+VOID FindKiWaitFunc(PULONG64 *KiWaitNeverAddr, PULONG64 *KiWaitAlwaysAddr)
+{
+ long Temp;
+ PUCHAR StartAddress,i;
+ UNICODE_STRING uniFuncName;
+ WCHAR wzFunName[] = L"KeSetTimer";
+ RtlInitUnicodeString(&uniFuncName,wzFunName);
+ StartAddress = (PUCHAR)MmGetSystemRoutineAddress(&uniFuncName);
+ for(i=StartAddress; iDriverSection;
+
+ while((PKLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Flink != FirstEntry)
+ {
+
+ if (Entry->BaseDllName.Buffer &&
+ nLen == Entry->BaseDllName.Length &&
+ MmIsAddressValid((PVOID)Entry->BaseDllName.Buffer) &&
+ !_wcsnicmp(wzNtoskrnl,(WCHAR*)Entry->BaseDllName.Buffer, nLen / sizeof(WCHAR)))
+ {
+ Ntoskrnl_KLDR_DATA_TABLE_ENTRY = (PVOID)Entry;
+ bRet = TRUE;
+ break;
+ }
+
+ Entry = (PKLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Flink;
+ }
+
+ // ûҵntoskrnl,ôʹԼ
+ if (!bRet)
+ {
+ Ntoskrnl_KLDR_DATA_TABLE_ENTRY = (PVOID)FirstEntry;
+ bRet = TRUE;
+ }
+ }
+
+ return bRet;
+}
+
+
+
+
+NTSTATUS EnumDrivers(PVOID OutBuffer, ULONG OutSize)
+{
+ NTSTATUS Status = STATUS_UNSUCCESSFUL;
+ PALL_DRIVERS DriversInfor = (PALL_DRIVERS)OutBuffer;
+ ULONG ulCount = (OutSize - sizeof(ALL_DRIVERS)) / sizeof(DRIVER_INFO);
+ if (!OutBuffer)
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ EnumDriverByLdrDataTableEntry(DriversInfor,ulCount);
+ if (ulCount >= DriversInfor->ulCount)
+ {
+ Status = STATUS_SUCCESS;
+ }
+ else
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ }
+
+ return Status;
+}
+
+
+
+
+VOID EnumDriverByLdrDataTableEntry(PALL_DRIVERS DriversInfor, ULONG_PTR ulCount)
+{
+ PKLDR_DATA_TABLE_ENTRY Entry = NULL, FirstEntry = NULL;
+ ULONG nMax = PAGE_SIZE;
+ ULONG i = 0;
+ KIRQL OldIrql;
+
+ FirstEntry = Entry = (PKLDR_DATA_TABLE_ENTRY)Ntoskrnl_KLDR_DATA_TABLE_ENTRY;
+
+ if (!FirstEntry || !DriversInfor)
+ {
+ return;
+ }
+ OldIrql = KeRaiseIrqlToDpcLevel();
+ __try
+ {
+ do
+ {
+ if ((ULONG_PTR)Entry->DllBase > SYSTEM_ADDRESS_START && Entry->SizeOfImage > 0)
+ {
+ ULONG_PTR Temp = DriversInfor->ulCount;
+ if (ulCount > Temp)
+ {
+
+ DriversInfor->Drivers[Temp].LodeOrder = ++i;
+ DriversInfor->Drivers[Temp].Base = (ULONG_PTR)Entry->DllBase;
+ DriversInfor->Drivers[Temp].Size = Entry->SizeOfImage;
+
+ if (IsUnicodeStringValid(&(Entry->FullDllName)))
+ {
+ wcsncpy(DriversInfor->Drivers[Temp].wzDriverPath, Entry->FullDllName.Buffer, Entry->FullDllName.Length);
+ }
+ else if (IsUnicodeStringValid(&(Entry->BaseDllName)))
+ {
+ wcsncpy(DriversInfor->Drivers[Temp].wzDriverPath, Entry->BaseDllName.Buffer, Entry->BaseDllName.Length);
+ }
+ }
+ DriversInfor->ulCount++;
+ }
+
+ Entry = (PKLDR_DATA_TABLE_ENTRY)Entry->InLoadOrderLinks.Flink;
+
+ }while(Entry && Entry != FirstEntry && nMax--);
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DbgPrint("LdrDataTable Exception!\r\n");
+ }
+
+ KeLowerIrql(OldIrql);
+}
+
+BOOLEAN IsUnicodeStringValid(PUNICODE_STRING uniString)
+{
+ BOOLEAN bRet = FALSE;
+
+ __try
+ {
+ if (uniString->Length > 0 &&
+ uniString->Buffer &&
+ MmIsAddressValid(uniString->Buffer) &&
+ MmIsAddressValid(&uniString->Buffer[uniString->Length / sizeof(WCHAR) - 1]))
+ {
+ bRet = TRUE;
+ }
+
+ }
+ __except(EXCEPTION_EXECUTE_HANDLER)
+ {
+ bRet = FALSE;
+ }
+
+ return bRet;
+}
+
+
+
+PVOID GetFunctionAddressByName(WCHAR *wzFunction)
+{
+ UNICODE_STRING uniFunction;
+ PVOID AddrBase = NULL;
+
+ if (wzFunction && wcslen(wzFunction) > 0)
+ {
+ RtlInitUnicodeString(&uniFunction, wzFunction); //ָ
+ AddrBase = MmGetSystemRoutineAddress(&uniFunction); //System һģ Ntosknrl.exe ExportTable
+ }
+
+ return AddrBase;
+}
+
+
+
+NTSTATUS RemoveDPCTimer(PVOID InBuffer)
+{
+ PREMOVE_DPCTIMER Temp = (PREMOVE_DPCTIMER)InBuffer;
+ ULONG_PTR TimerObject = Temp->TimerObject;
+ if (TimerObject&&MmIsAddressValid((PVOID)TimerObject))
+ {
+
+ if (KeCancelTimer((PKTIMER)TimerObject))
+ {
+ return STATUS_SUCCESS;
+ }
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+
+
+VOID UnloadDriver(PDRIVER_OBJECT DriverObject)
+{
+ UNICODE_STRING uniLinkName;
+ PDEVICE_OBJECT CurrentDeviceObject;
+ PDEVICE_OBJECT NextDeviceObject;
+
+ RtlInitUnicodeString(&uniLinkName,LINK_NAME);
+ IoDeleteSymbolicLink(&uniLinkName);
+ if (DriverObject->DeviceObject!=NULL)
+ {
+ CurrentDeviceObject = DriverObject->DeviceObject;
+ while(CurrentDeviceObject!=NULL)
+ {
+ NextDeviceObject = CurrentDeviceObject->NextDevice;
+ IoDeleteDevice(CurrentDeviceObject);
+ CurrentDeviceObject = NextDeviceObject;
+ }
+ }
+ DbgPrint("UnloadDriver\r\n");
+}
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.h b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.h
new file mode 100644
index 0000000..d3dc72e
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.h
@@ -0,0 +1,139 @@
+/***************************************************************************************
+* AUTHOR :
+* DATE : 2014-10-25
+* MODULE : DpcTimerDrv.H
+*
+* IOCTRL Sample Driver
+*
+* Description:
+* Demonstrates communications between USER and KERNEL.
+*
+****************************************************************************************
+* Copyright (C) 2010 .
+****************************************************************************************/
+
+
+#include
+#include
+
+#define CTL_GET_DPCTIMER \
+ CTL_CODE(FILE_DEVICE_UNKNOWN,0x830,METHOD_NEITHER,FILE_ANY_ACCESS)
+#define CTL_GET_DRIVER \
+ CTL_CODE(FILE_DEVICE_UNKNOWN,0x831,METHOD_NEITHER,FILE_ANY_ACCESS)
+
+#define CTL_REMOVEDPCTIMER \
+ CTL_CODE(FILE_DEVICE_UNKNOWN,0x832,METHOD_NEITHER,FILE_ANY_ACCESS)
+
+#define DEVICE_NAME L"\\Device\\DPCTimer"
+#define LINK_NAME L"\\DosDevices\\DPCTimerLink"
+
+#define MAX_PATH 260
+
+#define SYSTEM_ADDRESS_START32 0x80000000
+#define SYSTEM_ADDRESS_START64 0x80000000000
+
+typedef struct _REMOVE_DPCTIMER
+{
+ ULONG_PTR TimerObject;
+}REMOVE_DPCTIMER,*PREMOVE_DPCTIMER;
+
+typedef struct _DRIVER_INFO_
+{
+ ULONG_PTR LodeOrder;
+ ULONG_PTR Base;
+ ULONG_PTR Size;
+ ULONG_PTR DriverObject;
+ ULONG_PTR DirverStartAddress;
+ WCHAR wzDriverPath[MAX_PATH];
+ WCHAR wzKeyName[MAX_PATH];
+}DRIVER_INFO, *PDRIVER_INFO;
+
+typedef struct _ALL_DRIVERS_
+{
+ ULONG_PTR ulCount;
+ DRIVER_INFO Drivers[1];
+}ALL_DRIVERS, *PALL_DRIVERS;
+
+
+typedef struct _DPC_TIMER_
+{
+ ULONG_PTR TimerObject;
+ ULONG_PTR Period; //
+ ULONG_PTR TimeDispatch;
+ ULONG_PTR Dpc;
+}DPC_TIMER, *PDPC_TIMER;
+
+
+typedef struct _DPC_TIMER_INFOR_
+{
+ ULONG ulCnt;
+ ULONG ulRetCnt;
+ DPC_TIMER DpcTimer[1];
+}DPC_TIMER_INFOR, *PDPC_TIMER_INFOR;
+
+
+typedef struct _KLDR_DATA_TABLE_ENTRY64 {
+ LIST_ENTRY64 InLoadOrderLinks;
+ ULONG64 __Undefined1;
+ ULONG64 __Undefined2;
+ ULONG64 __Undefined3;
+ ULONG64 NonPagedDebugInfo;
+ ULONG64 DllBase;
+ ULONG64 EntryPoint;
+ ULONG SizeOfImage;
+ UNICODE_STRING64 FullDllName;
+ UNICODE_STRING64 BaseDllName;
+ ULONG Flags;
+ USHORT LoadCount;
+ USHORT __Undefined5;
+ ULONG64 __Undefined6;
+ ULONG CheckSum;
+ ULONG __padding1;
+ ULONG TimeDateStamp;
+ ULONG __padding2;
+} KLDR_DATA_TABLE_ENTRY64, *PKLDR_DATA_TABLE_ENTRY64;
+
+typedef struct _KLDR_DATA_TABLE_ENTRY32 {
+ LIST_ENTRY32 InLoadOrderLinks;
+ ULONG __Undefined1;
+ ULONG __Undefined2;
+ ULONG __Undefined3;
+ ULONG NonPagedDebugInfo;
+ ULONG DllBase;
+ ULONG EntryPoint;
+ ULONG SizeOfImage;
+ UNICODE_STRING32 FullDllName;
+ UNICODE_STRING32 BaseDllName;
+ ULONG Flags;
+ USHORT LoadCount;
+ USHORT __Undefined5;
+ ULONG __Undefined6;
+ ULONG CheckSum;
+ ULONG TimeDateStamp;
+} KLDR_DATA_TABLE_ENTRY32, *PKLDR_DATA_TABLE_ENTRY32;
+
+#ifdef _WIN64
+#define PKLDR_DATA_TABLE_ENTRY PKLDR_DATA_TABLE_ENTRY64
+#define SYSTEM_ADDRESS_START SYSTEM_ADDRESS_START64
+#else
+#define PKLDR_DATA_TABLE_ENTRY PKLDR_DATA_TABLE_ENTRY32
+#define SYSTEM_ADDRESS_START SYSTEM_ADDRESS_START32
+#endif
+
+VOID UnloadDriver(PDRIVER_OBJECT DriverObject);
+PVOID GetFunctionAddressByName(WCHAR *wzFunction);
+NTSTATUS DefaultDispatchFunction(PDEVICE_OBJECT DeviceObject,PIRP Irp);
+NTSTATUS EnumDpcTimer(PVOID OutBuffer);
+NTSTATUS DispatchControl(PDEVICE_OBJECT DeviceObject,PIRP Irp);
+NTSTATUS GetDpcTimerInformation_x64(PDPC_TIMER_INFOR DpcTimerInfor);
+VOID FindKiWaitFunc(PULONG64 *KiWaitNeverAddr, PULONG64 *KiWaitAlwaysAddr);
+KDPC* TransTimerDpcEx(
+ IN PKTIMER InTimer,
+ IN ULONGLONG InKiWaitNever,
+ IN ULONGLONG InKiWaitAlways);
+
+VOID EnumDriverByLdrDataTableEntry(PALL_DRIVERS DriversInfor, ULONG_PTR ulCount);
+NTSTATUS EnumDrivers(PVOID OutBuffer, ULONG OutSize);
+BOOLEAN GetKernelLdrDataTableEntry(PDRIVER_OBJECT DriverObject);
+BOOLEAN IsUnicodeStringValid(PUNICODE_STRING uniString);
+NTSTATUS RemoveDPCTimer(PVOID InBuffer);
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.sln b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.sln
new file mode 100644
index 0000000..c26c241
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.sln
@@ -0,0 +1,16 @@
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DpcTimerDrv", "DpcTimerDrv.vcxproj", "{4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ WinDDK|Win32 = WinDDK|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}.WinDDK|Win32.ActiveCfg = WinDDK|Win32
+ {4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}.WinDDK|Win32.Build.0 = WinDDK|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.suo b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.suo
new file mode 100644
index 0000000..fdee46d
Binary files /dev/null and b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.suo differ
diff --git a/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.vcxproj b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.vcxproj
new file mode 100644
index 0000000..9717c8b
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.vcxproj
@@ -0,0 +1,62 @@
+
+
+
+
+ WinDDK
+ Win32
+
+
+
+ {4EE67C57-BE79-4CD7-B3B0-94AECE62DB41}
+ Win32Proj
+ "DpcTimerDrv"
+
+
+
+
+
+
+
+ .sys
+ false
+ $(WLHBASE)\bin\x86\x86;$(WLHBASE)\bin\x86
+ $(WLHBASE)\inc\api;$(WLHBASE)\inc\crt;$(WLHBASE)\inc\ddk;$(WLHBASE)\inc
+
+ $(WLHBASE)\lib\win7\i386
+
+
+
+
+
+ _X86_;DBG=1
+ false
+ false
+ StdCall
+ CompileAsC
+
+
+
+
+ ntoskrnl.lib;hal.lib;wdm.lib;%(AdditionalDependencies)
+
+
+ true
+ Native
+ Driver
+ DriverEntry
+ true
+ 0x10000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.vcxproj.user b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.vcxproj.user
new file mode 100644
index 0000000..ace9a86
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/DpcTimerDrv.vcxproj.user
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimerDrv/clean.bat b/DpcTimer_x64/DpcTimerDrv/clean.bat
new file mode 100644
index 0000000..a92852f
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/clean.bat
@@ -0,0 +1,28 @@
+rem /////////////////
+rem / Add by ChiChou
+rem /
+rem / FileName:Clean.bat
+rem / Description:Clean
+rem /
+rem ////////////////
+rd .\bin /s /q
+rd .\WinDDK /s /q
+rd .\objchk_w2k_x86 /s /q
+rd .\objchk_wxp_x86 /s /q
+rd .\objchk_wnet_x86 /s /q
+rd .\objchk_wlh_x86 /s /q
+rd .\objfre_w2k_x86 /s /q
+rd .\objfre_wxp_x86 /s /q
+rd .\objfre_wnet_x86 /s /q
+rd .\objfre_wlh_x86 /s /q
+del .\*.log
+del .\*.err
+del .\*.xml
+rem ***** del VS2005 file *****
+del .\*.ncb
+del .\*.user
+del .\*.suo /A:H
+rem ***** del VS6.0 file *****
+del .\*.plg
+del .\*.opt
+exit
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimerDrv/ddkbuild.cmd b/DpcTimer_x64/DpcTimerDrv/ddkbuild.cmd
new file mode 100644
index 0000000..8acd7a4
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/ddkbuild.cmd
@@ -0,0 +1,1122 @@
+@echo off
+@set VERSION=V7.3
+@set OSR_DEBUG=off
+@if "%OS%"=="Windows_NT" goto :Prerequisites
+@echo This script requires Windows NT 4.0 or later to run properly!
+goto :EOF
+:Prerequisites
+:: Check whether FINDSTR is available. It's used to show warnings etc.
+findstr /? > NUL 2>&1 || echo "FINDSTR is a prerequisite but wasn't found!" && goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::
+:: $Id: ddkbuild.cmd 27 2008-09-06 12:02:06Z oliver $
+::
+:: This software is supplied for instructional purposes only.
+::
+:: OSR Open Systems Resources, Inc. (OSR) expressly disclaims any warranty
+:: for this software. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY
+:: OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
+:: THE IMPLIED WARRANTIES OF MECHANTABILITY OR FITNESS FOR A PARTICULAR
+:: PURPOSE. THE ENTIRE RISK ARISING FROM THE USE OF THIS SOFTWARE REMAINS
+:: WITH YOU. OSR's entire liability and your exclusive remedy shall not
+:: exceed the price paid for this material. In no event shall OSR or its
+:: suppliers be liable for any damages whatsoever (including, without
+:: limitation, damages for loss of business profit, business interruption,
+:: loss of business information, or any other pecuniary loss) arising out
+:: of the use or inability to use this software, even if OSR has been
+:: advised of the possibility of such damages. Because some states/
+:: jurisdictions do not allow the exclusion or limitation of liability for
+:: consequential or incidental damages, the above limitation may not apply
+:: to you.
+::
+:: OSR Open Systems Resources, Inc.
+:: 105 Route 101A Suite 19
+:: Amherst, NH 03031 (603) 595-6500 FAX: (603) 595-6503
+:: report bugs to
+:: alternatively report them via
+::
+::
+:: MODULE:
+::
+:: ddkbuild.cmd
+::
+:: ABSTRACT:
+::
+:: This script allows drivers to be built with Visual Studio 2002 through
+:: Visual Studio 2008 and possibly future versions. It will also work fine
+:: from the command line.
+:: If you are interested in a project wizard that makes use of this script,
+:: try DDKWizard from .
+::
+:: AUTHOR(S):
+::
+:: - OSR Open Systems Resources, Inc.
+:: - Oliver Schneider (ddkwizard.assarbad.net)
+::
+:: REQUIREMENTS:
+::
+:: Environment variables that must be set.
+:: %NT4BASE% - Set this up for "-NT4" builds (legacy, support not tested)
+:: %W2KBASE% - Set this up for "-W2K*" builds (legacy, support not tested)
+:: %WXPBASE% - Set this up for "-WXP*" builds
+:: %WNETBASE% - Set this up for "-WNET*" builds
+:: %WLHBASE% - Set this up for "-WLH*" builds
+:: %WDF_ROOT% - Must be set if attempting to do a WDF Build.
+::
+:: Examples:
+:: NT4BASE : could be "D:\NT4DDK"
+:: W2KBASE : could be "D:\Nt50DDK"
+:: WXPBASE : could be "D:\WINDDK\2600"
+:: WNETBASE: could be "D:\WINDDK\3790.1830" or "C:\WINDDK\3790"
+::
+:: COMMAND FORMAT:
+::
+:: Run the script without any parameters to get the whole help content!
+:: Note: "-WDF" has been tested with the 01.00.5054 version of the framework
+::
+:: RETURN CODES AND THEIR MEANING:
+::
+:: 001 == Unknown build type. Check the parameter
+:: 002 == No WDF_ROOT given using WDF build type.
+:: 003 == The DDK-specific base directory variable (NT4BASE, W2KBASE, WXPBASE,
+:: WNETBASE) is not set at all and could not be auto-detected!
+:: 004 == BASEDIR variable is empty. Check to see that the DDK-specific
+:: variable is set correctly (i.e. NT4BASE, W2KBASE, WXPBASE, WNETBASE)
+:: 005 == No mode (checked/free) was given. Check the respective parameter!
+:: 006 == No DIR or SOURCES file found in the given target directory.
+:: 007 == No target directory given.
+:: 008 == Given target directory does not exist.
+:: 009 == The SETENV script failed.
+::
+:: Note: If %OSR_ERRCODE% and %ERRORLEVEL% are equal, the return code stems
+:: from one of the tools being called during the build process.
+::
+:: BROWSE FILES:
+::
+:: This procedure supports the building of BROWSE files to be used by
+:: Visual Studio 6 and by Visual Studio.NET However, the BSCfiles created
+:: by bscmake for the two are not compatible. When this command procedure
+:: runs, it selects the first bscmake.exe found in the path. So, make sure
+:: that the correct bscmake.exe is in the path ...
+::
+:: Note that if using Visual Studio.NET the .BSC must be added to the project
+:: in order for the project to be browsed.
+:: Another alternative is the VS addon named "Visual Assist X" which will
+:: parse the header files - no more need for browse files.
+::
+:: COMPILERS:
+::
+:: If you are building NT4 you should really be using the VC6 compiler.
+:: Later versions of the DDK now contain the compiler and the linker. This
+:: procedure should use the correct compiler.
+::
+:: GENERAL COMMENTS:
+::
+:: This procedure has been cleaned up to be modular and easy to understand.
+::
+:: As of the Server 2003 SP1 DDK DDKBUILD now clears the NO_BROWSE_FILE and
+:: NO_BINPLACE environment variables so that users can use these features.
+::
+:: Starting with the Vista WDK, the output in the respective tool window
+:: in VS is in Unicode by default. This garbles the output from DDKBUILD
+:: and we therefore clear the environment variable VS_UNICODE_OUTPUT.
+::
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / MAIN function of the script
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:MAIN
+:: Building "stack frame"
+setlocal ENABLEEXTENSIONS & pushd .
+:: Check whether the REG utility is available
+reg /? > NUL 2>&1 && set OSR_REGAVAILABLE=1
+
+:: This is set by client-side keyword substitution
+set SVN_REVISION=$Revision: 27 $
+:: Extract the revision number from the revision keyword
+set SVN_REVISION=%SVN_REVISION:~0,-2%
+set SVN_REVISION=%SVN_REVISION:~11%
+:: This is set by client-side keyword substitution
+set SVN_REVDATE=$Date: 2008-09-06 12:02:06 +0000 (Sat, 06 Sep 2008) $
+:: Extract the date from the Date keyword
+set SVN_REVDATE=%SVN_REVDATE:~7,10%
+set VERSION=%VERSION%/r%SVN_REVISION%
+
+:: Init some special variables
+set OSR_VERSTR=OSR DDKBUILD.CMD %VERSION% (%SVN_REVDATE%) - OSR, Open Systems Resources, Inc.
+set OSR_PREBUILD_SCRIPT=ddkprebld.cmd
+set OSR_POSTBUILD_SCRIPT=ddkpostbld.cmd
+set OSR_SETENV_SCRIPT=ddkbldenv.cmd
+set OSR_ECHO=@echo DDKBLD:
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: Set error messages
+:: Possible codes: 1
+set ERR_UnknownBuildType=Unknown type of build. Please recheck parameters.
+:: Possible codes: 2
+set ERR_NoWdfRoot=WDF_ROOT is not defined, are you using 00.01.5054 or later?
+:: Possible codes: 3
+set ERR_BaseDirNotSet=To build using type %%OSR_TARGET%% you need to set the %%%%%%BASEDIRVAR%%%%%% environment variable to point to the %%BASEDIROS%% DDK base directory!
+:: Possible codes: 4
+set ERR_NoBASEDIR=NT4BASE, W2KBASE, WXPBASE and/or WNETBASE environment variable(s) not set. Environment variable(s) must be set by user according to DDK version(s) installed.
+:: Possible codes: 5
+set ERR_BadMode=^ must be 'checked', 'free', 'chk' or 'fre' (case-insensitive).
+:: Possible codes: 6
+set ERR_NoTarget=Target directory must contain a SOURCES or DIRS file.
+:: Possible codes: 7, 8
+set ERR_NoDir=The ^ parameter must be a valid directory.
+:: Possible codes: 9
+set ERR_SetEnvFailed=The SETENV script failed.
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: Clear the error code variable
+set OSR_ERRCODE=0
+set prefast_build=0
+
+:: Turn on tracing, use %OSR_TRACE% instead of ECHO
+if /i "%OSR_DEBUG%" == "on" (set OSR_TRACE=%OSR_ECHO% [TRACE]) else (set OSR_TRACE=rem)
+:: Turn on echoing of current line if %OSR_DEBUG% is set to "on"
+@echo %OSR_DEBUG%
+
+:: Output version string
+@echo %OSR_VERSTR%
+%OSR_TRACE% ^(Current module: ^"%~f0^"^)
+@echo.
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: Set the target platform variable
+set OSR_TARGET=%~1
+:: Remove any dashes in the variable
+if not "%OSR_TARGET%" == "" set OSR_TARGET=%OSR_TARGET:-=%
+:: Show help if the target parameter is empty after removal of the dashes
+if "%OSR_TARGET%" == "" goto :USAGE
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: In the build directory check for this script and call it if it exists.
+:: This allows to override any global system variable setting, if desired.
+if not "%3" == "" call :GetCustomEnvironment "%~f3"
+if not "%OSR_ERRCODE%" == "0" goto :USAGE
+:: Additional error handling for better usability
+:: These subroutines will also attempt to locate the requested DDK!!!
+set OSR_ERRCODE=3
+%OSR_TRACE% Checking whether the environment variable for the build type was set
+:: Calling as a subroutine has 2 advantages:
+:: 1. the script does not quit if the label was not found
+:: 2. we return to the line after the call and can check variables there
+call :%OSR_TARGET%Check > NUL 2>&1
+:: If the BASEDIROS/BASEDIRVAR variable is not defined, it means the subroutine did not exist!
+if not DEFINED BASEDIROS call :ShowErrorMsg 1 "%ERR_UnknownBuildType% (BASEDIROS)" & goto :USAGE
+if not DEFINED BASEDIRVAR call :ShowErrorMsg 1 "%ERR_UnknownBuildType% (BASEDIRVAR)" & goto :USAGE
+if not "%OSR_ERRCODE%" == "0" call :ShowErrorMsg %OSR_ERRCODE% "%ERR_BaseDirNotSet%" & goto :USAGE
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+set BASEDIR=%%%BASEDIRVAR%%%
+call :ResolveVar BASEDIR
+call :MakeShort BASEDIR "%BASEDIR%"
+:: Check for existing %BASEDIR%
+if "%BASEDIR%" == "" call :ShowErrorMsg 4 "%ERR_NoBASEDIR%" & goto :USAGE
+set PATH=%BASEDIR%\bin;%PATH%
+%OSR_TRACE% Now jump to the initialization of the commandline
+:: Calling as a subroutine has 2 advantages:
+:: 1. the script does not quit if the label was not found
+:: 2. we return to the line after the call and can check variables there
+call :%OSR_TARGET%Build
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+%OSR_TRACE% We returned from the variable initialization
+if not DEFINED OSR_CMDLINE call :ShowErrorMsg 1 "%ERR_UnknownBuildType% (OSR_CMDLINE)" & goto :USAGE
+
+%OSR_TRACE% Hurrah, all the variables have been initialized, continuing
+:: Proceed with common build steps
+goto :CommonBuild
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: Check whether the parameter makes sense and try to
+:: correct it if possible
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: These labels are for compatibility with the respective
+:: modes supported by another flavor of DDKBUILD.
+:WLH64Check
+:WLHA64Check
+:WLHXP64Check
+:WLHNET64Check
+:WLHNETA64Check
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:WLHCheck
+:WLHX64Check
+:WLHI64Check
+:WLHNETX64Check
+:WLHNETI64Check
+:WLHXPCheck
+:WLH2KCheck
+:WLHNETCheck
+set BASEDIROS=Windows Vista/Windows 2008 Server
+set BASEDIRVAR=WLHBASE
+:: Compatibility between BUILD and VS ... prevent pipes from being used
+%OSR_ECHO% Clearing %%VS_UNICODE_OUTPUT%% ...
+set VS_UNICODE_OUTPUT=
+:: Return to caller if the BASEDIR is already defined (either customized or global)
+if DEFINED %BASEDIRVAR% goto :CommonCheckNoErrorWithReturn
+call :DetectBaseDirTemp "6001.18000 6000"
+if DEFINED BASEDIRTEMP if exist "%BASEDIRTEMP%" goto :CommonCheckSetVarWithReturn
+goto :CommonCheckErrorNotSupportedWithReturn
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: These labels are for compatibility with the respective
+:: modes supported by another flavor of DDKBUILD.
+:WNETW2KCheck
+:WNETA64Check
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:WNET2KCheck
+:WNETXPCheck
+:WNETWXPCheck
+:WNETXP64Check
+:WNET64Check
+:WNETI64Check
+:WNETAMD64Check
+:WNETX64Check
+:WNETCheck
+set BASEDIROS=Windows 2003 Server
+set BASEDIRVAR=WNETBASE
+:: Return to caller if the BASEDIR is already defined (either customized or global)
+if DEFINED %BASEDIRVAR% goto :CommonCheckNoErrorWithReturn
+call :DetectBaseDirTemp "3790.1830 3790.1218 3790"
+if DEFINED BASEDIRTEMP if exist "%BASEDIRTEMP%" goto :CommonCheckSetVarWithReturn
+goto :CommonCheckErrorNotDetectedWithReturn
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: These labels are for compatibility with the respective
+:: modes supported by another flavor of DDKBUILD.
+:XPCheck
+:XP64Check
+:XPW2KCheck
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:WXP64Check
+:WXPI64Check
+:WXPCheck
+:WXP2KCheck
+set BASEDIROS=Windows XP
+set BASEDIRVAR=WXPBASE
+:: Other flavor of DDKBUILD
+if not DEFINED WXPBASE if DEFINED XPBASE set BASEDIRVAR=XPBASE
+:: Return to caller if the BASEDIR is already defined (either customized or global)
+if DEFINED %BASEDIRVAR% goto :CommonCheckNoErrorWithReturn
+call :DetectBaseDirTemp "2600.1106 2600"
+if DEFINED BASEDIRTEMP if exist "%BASEDIRTEMP%" goto :CommonCheckSetVarWithReturn
+goto :CommonCheckErrorNotDetectedWithReturn
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:W2K64Check
+:W2KI64Check
+:W2KCheck
+set BASEDIROS=Windows 2000
+set BASEDIRVAR=W2KBASE
+:: Return to caller
+if DEFINED %BASEDIRVAR% goto :CommonCheckNoErrorWithReturn
+call :CommonCheckMsg2
+goto :CommonCheckErrorNotSupportedWithReturn
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:NT4Check
+set BASEDIROS=Windows NT4
+set BASEDIRVAR=NT4BASE
+:: Return to caller
+if DEFINED %BASEDIRVAR% goto :CommonCheckNoErrorWithReturn
+call :CommonCheckMsg2
+goto :CommonCheckErrorNotSupportedWithReturn
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:CommonCheckMsg1
+echo.
+%OSR_ECHO% WARNING: %%%BASEDIRVAR%%% NOT SET!
+%OSR_ECHO% Attempting to auto-detect the installation folder and set %%%BASEDIRVAR%%%.
+%OSR_ECHO% (If this fails *you* will have to set it!)
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:CommonCheckMsg2
+echo.
+%OSR_ECHO% WARNING:
+%OSR_ECHO% Auto-detection of the folder settings is not supported for the requested DDK.
+%OSR_ECHO% Please set %%%BASEDIRVAR%%% yourself!
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:CommonCheckSetVarWithReturn
+%OSR_ECHO% Found!
+echo.
+set %BASEDIRVAR%=%BASEDIRTEMP%
+set BASEDIRTEMP=
+:: Tell the caller it was successful
+:CommonCheckNoErrorWithReturn
+set OSR_ERRCODE=0
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:CommonCheckErrorNotDetectedWithReturn
+echo.
+%OSR_ECHO% None of the usual default paths works. Set %%%BASEDIRVAR%%% manually!
+:CommonCheckErrorNotSupportedWithReturn
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: Initialize variables specific to the respective platform
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+::
+:: Valid parameters for setenv in different DDKs/WDKs:
+::
+:: 2600 - "setenv [fre|chk] [64] [hal]"
+:: 2600.1106 - "setenv [fre|chk] [64] [hal] [WXP|W2K]"
+:: 3790 - "setenv [fre|chk] [64|AMD64] [hal] [WXP|WNET|W2K]"
+:: 3790.1830 - "setenv [fre|chk] [64|AMD64] [hal] [WXP|WNET|W2K] [no_prefast] [bscmake]"
+:: 6000 - "setenv [fre|chk] [64|AMD64] [hal] [WLH|WXP|WNET|W2K] [bscmake]"
+:: 6001.18000 - "setenv [fre|chk] [64|x64] [hal] [WLH|WXP|WNET|W2K] [bscmake]"
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: NT 4.0 build using NT4 DDK
+:NT4Build
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% "%%MSDEVDIR%%"
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: W2K build for 32bit using WXP DDK
+:XPW2KBuild
+:WXP2KBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\w2k\set2k.bat" %%BASEDIR%% %%BuildMode%%
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: W2K build for 64bit (Intel) using W2K DDK
+:W2K64Build
+:W2KI64Build
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv64.bat" %%BASEDIR%% %%BuildMode%%
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: W2K build for 32bit using W2K DDK
+:W2KBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%%
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WXP build for 64bit (Intel) using WXP DDK
+:XP64Build
+:WXP64Build
+:WXPI64Build
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% 64
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WXP build for 32bit using WXP DDK
+:XPBuild
+:WXPBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%%
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: W2K build for 32bit using WNET DDK
+:WNETW2KBuild
+:WNET2KBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% W2K %%BuildMode%%
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WXP build for 32bit using WNET DDK
+:WNETXPBuild
+:WNETWXPBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% WXP
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WXP build for 64bit using WNET DDK
+:WNETXP64Build
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% 64 WXP
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WNET build for 64bit (Intel) using WNET DDK
+:WNET64Build
+:WNETI64Build
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% 64 WNET
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WNET build for 64bit (AMD) using WNET DDK
+:WNETA64Build
+:WNETAMD64Build
+:WNETX64Build
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% AMD64 WNET
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WNET build for 32bit using WNET DDK
+:WNETBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%%
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WLH build for 32bit using WLH DDK
+:WLHBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% WLH
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WLH build for 64bit (AMD) using WLH DDK
+:WLHA64Build
+:WLHX64Build
+call :DetectVistaWDK
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% %OSR_AMD64FLAG% WLH
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WLH build for 64bit (Intel) using WLH DDK
+:WLH64Build
+:WLHI64Build
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% 64 WLH
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WNET build for 64bit (AMD) using WLH DDK
+:WLHNETA64Build
+:WLHNETX64Build
+call :DetectVistaWDK
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% %OSR_AMD64FLAG% WNET
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WNET build for 64bit (Intel) using WLH DDK
+:WLHNET64Build
+:WLHNETI64Build
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% 64 WNET
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WXP build for 32bit using WLH DDK
+:WLHXPBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% WXP
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WXP build for 64bit (Intel) using WLH DDK
+:WLHXP64Build
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% 64 WXP
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: W2K build for 32bit using WLH DDK
+:WLH2KBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% W2K
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: WNET build for 32bit using WLH DDK
+:WLHNETBuild
+set OSR_CMDLINE="%%BASEDIR%%\bin\setenv.bat" %%BASEDIR%% %%BuildMode%% WNET
+goto :EOF
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: All builds go here for the rest of the procedure. Now,
+:: we are getting ready to call build. The big problem
+:: here is to figure our the name of the buildxxx files
+:: being generated for the different platforms.
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:CommonBuild
+:: Remove first command line arg
+shift
+call :SetMode %1
+if not "%OSR_ERRCODE%" == "0" call :ShowErrorMsg %OSR_ERRCODE% "%ERR_BadMode%" & goto :USAGE
+set OSR_BUILDNAME=%OSR_TARGET% (%BuildMode%) using the %BASEDIROS% DDK and %%%BASEDIRVAR%%%
+
+call :CheckTargets %2
+if "%OSR_ERRCODE%" == "6" call :ShowErrorMsg %OSR_ERRCODE% "%ERR_NoTarget%" & goto :USAGE
+if not "%OSR_ERRCODE%" == "0" call :ShowErrorMsg %OSR_ERRCODE% "%ERR_NoDir%" & goto :USAGE
+
+:: Resolve any variables in the command line string
+call :ResolveVar OSR_CMDLINE
+
+pushd .
+set ERRORLEVEL=0
+:: This external script prepares the build environment (e.g. setenv.bat)
+call %OSR_CMDLINE%
+:: Will only work with newer SETENV.BAT versions, but will be helpful in this case.
+if not "%ERRORLEVEL%" == "0" call :ShowErrorMsg 9 "%ERR_SetEnvFailed%" & goto :USAGE
+popd
+
+:: ----------------------------------------------------------------------------
+:: Setting global variables for the scope of this CMD session
+set NO_BROWSER_FILE=
+set NO_BINPLACE=
+set buildDirectory=%~fs2
+call :MakeShort buildDirectory "%buildDirectory%"
+set buildDirectory_raw=%2
+set buildDirectory_fname=%~n2
+%OSR_TRACE% buildDirectory == %buildDirectory%
+%OSR_TRACE% buildDirectory_raw == %buildDirectory_raw%
+%OSR_TRACE% buildDirectory_fname == %buildDirectory_fname%
+
+set mpFlag=-M
+if "%BUILD_ALT_DIR%" == "" goto :NT4
+
+:: W2K sets this!
+set OSR_EXT=%BUILD_ALT_DIR%
+set mpFlag=-MI
+
+:NT4
+if "%NUMBER_OF_PROCESSORS%" == "" set mpFlag=
+if "%NUMBER_OF_PROCESSORS%" == "1" set mpFlag=
+
+:: Set additional variables at this point or do whatever you please
+@if exist "%buildDirectory%\%OSR_PREBUILD_SCRIPT%" @(
+ %OSR_ECHO% ^>^> Performing pre-build steps [%OSR_PREBUILD_SCRIPT%] ...
+ pushd "%buildDirectory%"
+ call "%OSR_PREBUILD_SCRIPT%" > "%TEMP%\%OSR_PREBUILD_SCRIPT%.tmp"
+ for /f "tokens=*" %%x in ('type "%TEMP%\%OSR_PREBUILD_SCRIPT%.tmp"') do @(
+ %OSR_ECHO% %%x
+ )
+ if exist "%TEMP%\%OSR_PREBUILD_SCRIPT%.tmp" del /f /q "%TEMP%\%OSR_PREBUILD_SCRIPT%.tmp"
+ popd
+ %OSR_ECHO% ^<^< Finished pre-build steps [%OSR_PREBUILD_SCRIPT%] ...
+)
+:: Save the current directory (before changing into the build directory!)
+:: AFTERPREBUILD
+pushd .
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: Determine the settings of flags, WDF and PREFAST in
+:: other words what was set for %3 and beyond....
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+%OSR_ECHO% %OSR_BUILDNAME%
+set OSR_ARGS= + argument(s):
+if not "%3" == "" set OSR_ARGS=%OSR_ARGS% %3
+if not "%4" == "" set OSR_ARGS=%OSR_ARGS% %4
+if not "%5" == "" set OSR_ARGS=%OSR_ARGS% %5
+if /i "%OSR_ARGS%" == " + argument(s):" set OSR_ARGS=
+%OSR_ECHO% Directory: %buildDirectory%%OSR_ARGS%
+%OSR_ECHO% %BASEDIRVAR%: %BASEDIR%
+
+cd /D %~s2
+set bFlags=-Ze
+set bscFlags=
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:ContinueParsing
+if "%3" == "" goto :DONE
+if "%3" == "/a" goto :RebuildallFound
+if /i "%3" == "-WDF" goto :WDFFound
+if /i "%3" == "-PREFAST" goto :PrefastFound
+set bscFlags=/n
+set bFlags=%bFlags% %3
+:: Remove next arg
+shift
+goto :ContinueParsing
+
+:WDFFound
+shift
+:: Note, that the setwdf.bat is called from setenv.bat in the WDK,
+:: therefore we skip it.
+if /i "%BASEDIRVAR%" == "WLHBASE" goto :WDFOkay
+if "%WDF_ROOT%" == "" call :ShowErrorMsg 2 "%ERR_NoWdfRoot%" & goto :USAGE
+pushd .
+if exist "%WDF_ROOT%\set_wdf_env.cmd" call "%WDF_ROOT%\set_wdf_env.cmd"
+popd
+:WDFOkay
+goto :ContinueParsing
+
+:PrefastFound
+shift
+set prefast_build=1
+goto :ContinueParsing
+
+:RebuildallFound
+shift
+set bscFlags=/n
+set bFlags=%bFlags:-Ze=-cfeZ%
+set bFlags=%bFlags: -cZ=%
+goto :ContinueParsing
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:DONE
+for %%x in (build%OSR_EXT%.err build%OSR_EXT%.wrn build%OSR_EXT%.log prefast%OSR_EXT%.log) do @(
+ if exist "%%x" del /f /q "%%x"
+)
+
+if not "%prefast_build%" == "0" goto :RunPrefastBuild
+%OSR_ECHO% Run build %mpFlag% %bFlags% for %BuildMode% version in %buildDirectory_raw%
+pushd .
+build %mpFlag% %bFlags%
+popd
+goto :BuildComplete
+
+:RunPrefastBuild
+%OSR_ECHO% Run prefast build %mpFlag% %bFlags% for %BuildMode% version in %buildDirectory_raw%
+setlocal ENABLEEXTENSIONS & pushd .
+set PREFASTLOG=PREfast_defects_%OSR_EXT%.xml
+prefast /log=%PREFASTLOG% /reset build %mpFlag% %bFlags% > NUL 2>&1
+if "%errorlevel%" GTR "0" set OSR_ERRCODE=%errorlevel%
+prefast /log=%PREFASTLOG% list > prefast%OSR_EXT%.log
+%OSR_ECHO% The PREfast logfile is ^"%prefastlog%^"!
+popd & endlocal
+
+:BuildComplete
+if not "%errorlevel%" == "0" set OSR_ERRCODE=%errorlevel%
+
+@echo %OSR_DEBUG%
+:: Assume that the onscreen errors are complete!
+setlocal
+set WARNING_FILE_COUNT=0
+if exist "build%OSR_EXT%.log" for /f "tokens=*" %%x in ('findstr "warning[^.][DRCLU][0-9][0-9]* error[^.][DRCLU][0-9][0-9]*" "build%OSR_EXT%.log"') do @(
+ set /a WARNING_FILE_COUNT=%WARNING_FILE_COUNT%+1
+)
+if not "%WARNING_FILE_COUNT%" == "0" (
+ %OSR_ECHO% ================ Build warnings =======================
+ if exist "build%OSR_EXT%.log" for /f "tokens=*" %%x in ('findstr "warning[^.][DRCLU][0-9][0-9]* error[^.][DRCLU][0-9][0-9]*" "build%OSR_EXT%.log"') do @(
+ @echo %%x
+ )
+)
+set WARNING_FILE_COUNT_PRE=0
+if exist "prefast%OSR_EXT%.log" for /f "tokens=*" %%x in ('findstr "warning[^.][CLU]*" "prefast%OSR_EXT%.log"') do @(
+ set /a WARNING_FILE_COUNT_PRE=%WARNING_FILE_COUNT_PRE%+1
+)
+:: Reset if this is no PREfast build
+if "%prefast_build%" == "0" set WARNING_FILE_COUNT_PRE=0
+if not "%WARNING_FILE_COUNT_PRE%" == "0" (
+ %OSR_ECHO% =============== PREfast warnings ======================
+ if exist "prefast%OSR_EXT%.log" for /f "tokens=*" %%x in ('findstr "warning[^.][CLU]*" "prefast%OSR_EXT%.log"') do @(
+ @echo %%x
+ )
+)
+set /a WARNING_FILE_COUNT=%WARNING_FILE_COUNT%+%WARNING_FILE_COUNT_PRE%
+if not "%WARNING_FILE_COUNT%" == "0" (
+ %OSR_ECHO% =======================================================
+)
+endlocal
+@echo.
+%OSR_ECHO% Build complete
+%OSR_ECHO% Building browse information files
+if exist "buildbrowse.cmd" call "buildbrowse.cmd" & goto :postBuildSteps
+set sbrlist=sbrList.txt
+if not exist sbrList%CPU%.txt goto :sbrDefault
+set sbrlist=sbrList%CPU%.txt
+
+:sbrDefault
+if not exist %sbrlist% goto :postBuildSteps
+:: Prepend blank space
+if not "%bscFlags%" == "" set bscFlags= %bscFlags%
+:: bscmake%bscFlags% prevents a double blank space ...
+bscmake%bscFlags% @%sbrlist%
+
+:: Perform whatever post-build steps
+:postBuildSteps
+:: Restore the current directory (after changing into the build directory!)
+:: Search upwards for "AFTERPREBUILD" to find the corresponding PUSHD
+popd
+@if exist "%buildDirectory%\%OSR_POSTBUILD_SCRIPT%" @(
+ %OSR_ECHO% ^>^> Performing post-build steps [%OSR_POSTBUILD_SCRIPT%] ...
+ pushd "%buildDirectory%"
+ call "%OSR_POSTBUILD_SCRIPT%" > "%TEMP%\%OSR_POSTBUILD_SCRIPT%.tmp"
+ for /f "tokens=*" %%x in ('type "%TEMP%\%OSR_POSTBUILD_SCRIPT%.tmp"') do @(
+ %OSR_ECHO% %%x
+ )
+ if exist "%TEMP%\%OSR_POSTBUILD_SCRIPT%.tmp" del /f /q "%TEMP%\%OSR_POSTBUILD_SCRIPT%.tmp"
+ popd
+ %OSR_ECHO% ^<^< Finished post-build steps [%OSR_POSTBUILD_SCRIPT%] ...
+)
+goto :END
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ MAIN function of the script
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / GetCustomEnvironment
+:: First parameter is the "directory" that supposedly contains the SOURCES
+:: or DIRS file (and the build scripts)
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:GetCustomEnvironment
+pushd .
+call :CheckTargets "%~f1"
+@if not "%OSR_ERRCODE%" == "0" @(
+ echo.
+ %OSR_ECHO% The target directory seemed to not contain a DIRS or SOURCES file
+ %OSR_ECHO% when trying to set a custom environment! Quitting.
+ set buildDirectory=%~f1
+ if "%OSR_ERRCODE%" == "6" call :ShowErrorMsg %OSR_ERRCODE% "%ERR_NoTarget%" & goto :GetCustomEnvironment_ret
+ call :ShowErrorMsg %OSR_ERRCODE% "%ERR_NoDir%" & goto :GetCustomEnvironment_ret
+ goto :GetCustomEnvironment_ret
+)
+:: If the user provided a script to customize the environment, execute it.
+@if exist "%~f1\%OSR_SETENV_SCRIPT%" @(
+ %OSR_ECHO% ^>^> Setting custom environment variables [%OSR_SETENV_SCRIPT%] ...
+ pushd "%~f1"
+ call "%OSR_SETENV_SCRIPT%" > "%TEMP%\%OSR_SETENV_SCRIPT%.tmp"
+ for /f "tokens=*" %%x in ('type "%TEMP%\%OSR_SETENV_SCRIPT%.tmp"') do @(
+ %OSR_ECHO% %%x
+ )
+ if exist "%TEMP%\%OSR_SETENV_SCRIPT%.tmp" del /f /q "%TEMP%\%OSR_SETENV_SCRIPT%.tmp"
+ popd
+ %OSR_ECHO% ^<^< Finished setting custom environment variables [%OSR_SETENV_SCRIPT%] ...
+)
+:GetCustomEnvironment_ret
+popd
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ GetCustomEnvironment
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / SetMode
+:: Subroutine to validate the mode of the build passed in. It must be free,
+:: FREE, fre, FRE or checked, CHECKED, chk, CHK. Anything else is an error.
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:SetMode
+set BuildMode=
+if /i "%OSR_TARGET%" == "WLH2K" goto :SetModeWLH2K
+for %%f in (free fre) do if /i "%%f" == "%1" set BuildMode=free
+for %%f in (checked chk) do if /i "%%f" == "%1" set BuildMode=checked
+goto :SetModeCommonEnd
+:SetModeWLH2K
+for %%f in (free fre) do if /i "%%f" == "%1" set BuildMode=f
+for %%f in (checked chk) do if /i "%%f" == "%1" set BuildMode=c
+:SetModeCommonEnd
+%OSR_TRACE% Mode set to ^"%BuildMode%^"
+if "%BuildMode%" == "" set OSR_ERRCODE=5
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ SetMode
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / CheckTargets subroutine
+:: Subroutine to validate that the target directory exists and that there is
+:: either a DIRS or SOURCES and MakeFile in it.
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:CheckTargets
+:: Building "stack frame"
+setlocal & pushd . & set OSR_ERRCODE=0
+set lTarget=%~1
+if not "%lTarget%" == "" goto :CheckTargets1
+set OSR_ERRCODE=7
+goto :CheckTargets_ret
+:CheckTargets1
+if exist "%lTarget%" goto :CheckTargets2
+set OSR_ERRCODE=8
+goto :CheckTargets_ret
+:CheckTargets2
+if not exist "%lTarget%\DIRS" goto :CheckTargets3
+set OSR_ERRCODE=0
+goto :CheckTargets_ret
+:CheckTargets3
+if exist "%lTarget%\SOURCES" goto :CheckTargets4
+set OSR_ERRCODE=6
+goto :CheckTargets_ret
+:CheckTargets4
+if exist "%lTarget%\MAKEFILE" goto :CheckTargets5
+set OSR_ERRCODE=6
+goto :CheckTargets_ret
+:CheckTargets5
+set OSR_ERRCODE=0
+:CheckTargets_ret
+:: Cleaning "stack frame" and returning error code into global scope
+popd & endlocal & set OSR_ERRCODE=%OSR_ERRCODE%
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ CheckTargets subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / ResolveVar subroutine
+:: There is only one parameter, the name of the variable to be resolved!
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:ResolveVar
+:: Get the name of the variable we are working with
+setlocal ENABLEEXTENSIONS & set VAR_NAME=%1
+set VAR_TEMPRET2=%%%VAR_NAME%%%
+:ResolveVarLoop
+set VAR_TEMPRET1=%VAR_TEMPRET2%
+set VAR_TEMPRET2=%VAR_TEMPRET1%
+for /f "tokens=*" %%i in ('echo %VAR_TEMPRET1%') do (
+ set VAR_TEMPRET2=%%i
+)
+if not "%VAR_TEMPRET1%" == "%VAR_TEMPRET2%" goto :ResolveVarLoop
+:: Re-export the variable out of the local scope
+endlocal & set %VAR_NAME%=%VAR_TEMPRET1%
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ ResolveVar subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / MakeShort subroutine
+:: Two parameters. First parameter is the variable name, second is the path
+:: to convert into a short filename.
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:MakeShort
+setlocal ENABLEEXTENSIONS
+:: Get the name of the variable we are working with and the path to convert
+set VAR_NAME=%~1
+set PATH_SHORT=%~dpns2
+set PATH_EXTSHORT=%~xs2
+if not "" == "%PATH_EXTSHORT%" set PATH_EXTSHORT=%PATH_EXTSHORT:~0,4%
+set PATH_SHORT=%PATH_SHORT%%PATH_EXTSHORT%
+endlocal & set %VAR_NAME%=%PATH_SHORT%
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ MakeShort subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / ErrorWithUsage subroutine
+:: This one will take the passed in parameters and build a nice error
+:: message which is returned to the user along with the usage hints.
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:ShowErrorMsg
+@set OSR_ERRCODE=%~1
+@set OSR_ERRMSG=%~2
+@set OSR_ERRMSG=%OSR_ERRMSG:'="%
+@set OSR_ERRMSG=ERROR #%OSR_ERRCODE%: %OSR_ERRMSG%
+@echo.
+%OSR_ECHO% %OSR_ERRMSG%
+if DEFINED buildDirectory %OSR_ECHO% -^> Target directory: %buildDirectory%
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ ErrorWithUsage subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / SetVar subroutine
+:: Param1 == name of the variable, Param2 == value to be set for the variable
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:SetVar
+:: Get the name of the variable we are working with
+setlocal ENABLEEXTENSIONS & set VAR_NAME=%1
+endlocal & set %VAR_NAME%=%~2
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ SetVar subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / DetectVistaWDK subroutine
+:: No parameters expected
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:DetectVistaWDK
+setlocal ENABLEEXTENSIONS
+:: Newer flag (starting with W2K8) is default
+set OSR_AMD64FLAG=x64
+:: The Vista WDK accepted *only* "AMD64", the newer W2K8 WDK accepts only "x64"
+:: We detect the older one by checking the setenv.bat for a certain string
+findstr /C:"Windows Server Longhorn" "%BASEDIR%\bin\setenv.bat" > NUL 2>&1 && set OSR_AMD64FLAG=AMD64
+endlocal & set OSR_AMD64FLAG=%OSR_AMD64FLAG%
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ DetectVistaWDK subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / DetectBaseDirTemp subroutine
+:: The first parameter is the list of directory names to check, separated by
+:: blank spaces.
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:DetectBaseDirTemp
+:: Get the name of the variable we are working with
+if "%~1" == "" goto :EOF
+setlocal ENABLEEXTENSIONS
+call :CommonCheckMsg1
+:: Try to find an installed DDK/WDK from the registry keys
+if DEFINED OSR_REGAVAILABLE if not "%OSR_REGAVAILABLE%" == "0" (
+ for %%i in (%~1) do @(
+ call :RegTryBaseDirTemp "%%i"
+ )
+)
+:: Try all the "default" locations
+if not DEFINED BASEDIRTEMP (
+ for %%i in (%~1) do @(
+ for %%a in (WINDDK DDK) do @(
+ call :BruteTryBaseDirTemp "%SystemDrive%\%%a\%%i"
+ call :BruteTryBaseDirTemp "%ProgramFiles%\%%a\%%i"
+ )
+ )
+)
+endlocal & set BASEDIRTEMP=%BASEDIRTEMP%
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ DetectBaseDirTemp subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / RegTryBaseDirTemp subroutine
+:: Attempt to find the install key in the registry.
+:: This functions tests old-style DDKs and new-style WDKs.
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:RegTryBaseDirTemp
+if DEFINED BASEDIRTEMP if exist "%BASEDIRTEMP%" goto :EOF
+setlocal ENABLEEXTENSIONS
+call :RegTryBaseDirTempSingle "%~1" "LFNDirectory" BASEDIRTEMP
+if DEFINED BASEDIRTEMP if exist "%BASEDIRTEMP%" goto :RegTryBaseDirTemp_EOF
+call :RegTryBaseDirTempSingle "%~1\Setup" "BUILD" BASEDIRTEMP
+if DEFINED BASEDIRTEMP if exist "%BASEDIRTEMP%" goto :RegTryBaseDirTemp_EOF
+if not DEFINED BASEDIRTEMP (endlocal & goto :EOF)
+:RegTryBaseDirTemp_EOF
+%OSR_ECHO% Found directory (%BASEDIRTEMP%) from install key
+endlocal & set BASEDIRTEMP=%BASEDIRTEMP% & goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ RegTryBaseDirTemp subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / RegTryBaseDirTempSingle subroutine
+:: Attempt to find the install key in the registry.
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:RegTryBaseDirTempSingle
+setlocal ENABLEEXTENSIONS
+set REGSUBKEY=%~1
+set REGVALUE=%~2
+set VARIABLETOSET=%~3
+set REGMAINKEY=HKLM\SOFTWARE\Microsoft\WINDDK
+:: Test whether we can read the value below this key
+reg query "%REGMAINKEY%\%REGSUBKEY%" /v "%REGVALUE%" > NUL 2>&1 || goto :RegTryBaseDirTempSingle_WOW64
+for /f "tokens=2*" %%i in ('reg query "%REGMAINKEY%\%REGSUBKEY%" /v "%REGVALUE%"^|findstr /C:"%REGVALUE%"') do @(
+ call :SetVar _SETVARIABLE "%%j"
+)
+endlocal & set %VARIABLETOSET%=%_SETVARIABLE%
+:RegTryBaseDirTempSingle_WOW64
+set REGMAINKEY=HKLM\SOFTWARE\Wow6432Node\Microsoft\WINDDK
+:: Test whether we can read the value below this key
+reg query "%REGMAINKEY%\%REGSUBKEY%" /v "%REGVALUE%" > NUL 2>&1 || goto :RegTryBaseDirTempSingle_EOF
+for /f "tokens=2*" %%i in ('reg query "%REGMAINKEY%\%REGSUBKEY%" /v "%REGVALUE%"^|findstr /C:"%REGVALUE%"') do @(
+ call :SetVar _SETVARIABLE "%%j"
+)
+endlocal & set %VARIABLETOSET%=%_SETVARIABLE%
+:RegTryBaseDirTempSingle_EOF
+endlocal
+goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ RegTryBaseDirTempSingle subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: / BruteTryBaseDirTemp subroutine
+:: Brute-force test the given directory.
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:BruteTryBaseDirTemp
+if DEFINED BASEDIRTEMP if exist "%BASEDIRTEMP%" goto :EOF
+setlocal ENABLEEXTENSIONS
+:: We will not overwrite BASETEMPDIR if it has been set and is valid
+:: Just try
+set BASEDIRTEMP=%~1
+%OSR_ECHO% Trying %BASEDIRTEMP% ...
+if not exist "%BASEDIRTEMP%" (endlocal & goto :EOF)
+endlocal & set BASEDIRTEMP=%BASEDIRTEMP% & goto :EOF
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: \ BruteTryBaseDirTemp subroutine
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:: Usage output
+:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:USAGE
+@echo.
+@echo USAGE:
+@echo ======
+@echo %~n0 ^ ^ ^ [flags] [-WDF] [-PREFAST]
+@echo.
+@echo Values for ^:
+@echo --------------------------------------------------------------------------
+@echo Target platform and OS ^| Miscellaneous
+@echo --------------------------^|-----------------------------------------------
+@echo Target ^| Windows ^| CPU ^| Base directory ^| Target alias(es)
+@echo ------------^|-------------^|---------^|----------------^|--------------------
+@echo -W2K ^| 2000 ^| x86 ^| %%W2KBASE%% ^|
+@echo -W2K64 ^| 2000 ^| Itanium ^| %%W2KBASE%% ^| -W2KI64
+@echo -WXP ^| XP ^| x86 ^| %%WXPBASE%% ^| -XP
+@echo -WXP64 ^| XP ^| Itanium ^| %%WXPBASE%% ^| -WXPI64, -XP64
+@echo -WXP2K ^| 2000 ^| x86 ^| %%WXPBASE%% ^| -XPW2K
+@echo -WNET ^| 2003 ^| x86 ^| %%WNETBASE%% ^|
+@echo -WNET64 ^| 2003 ^| Itanium ^| %%WNETBASE%% ^| -WNETI64
+@echo -WNETXP ^| XP ^| x86 ^| %%WNETBASE%% ^|
+@echo -WNETXP64 ^| XP ^| Itanium ^| %%WNETBASE%% ^|
+@echo -WNETAMD64 ^| 2003/XP x64 ^| x64 ^| %%WNETBASE%% ^| -WNETX64, -WNETA64
+@echo -WNET2K ^| 2000 SP3 ^| x86 ^| %%WNETBASE%% ^| -WNETW2K
+@echo -WLH ^| Vista/2008 ^| x86 ^| %%WLHBASE%% ^|
+@echo -WLH2K ^| 2000 SP4 ^| x86 ^| %%WLHBASE%% ^|
+@echo -WLHXP ^| XP ^| x86 ^| %%WLHBASE%% ^|
+@echo -WLHXP64 ^| XP ^| Itanium ^| %%WLHBASE%% ^|
+@echo -WLHNET ^| 2003 ^| x86 ^| %%WLHBASE%% ^|
+@echo -WLHNETI64 ^| 2003 ^| Itanium ^| %%WLHBASE%% ^| -WLHNET64
+@echo -WLHNETX64 ^| 2003/XP x64 ^| x64 ^| %%WLHBASE%% ^| -WLHNETA64
+@echo -WLHI64 ^| Vista/2008 ^| Itanium ^| %%WLHBASE%% ^| -WLH64
+@echo -WLHX64 ^| Vista/2008 ^| x64 ^| %%WLHBASE%% ^| -WLHA64
+@echo -NT4 ^| NT 4.0 ^| x86 ^| %%NT4BASE%% ^|
+@echo --------------------------------------------------------------------------
+@echo Support for NT4 and W2K DDKs is deprecated and not checked anymore
+@echo in new versions. It may or may not work properly.
+@echo --------------------------------------------------------------------------
+@echo.
+@echo Values for ^:
+@echo checked, chk indicates a checked build
+@echo free, fre indicates a free build
+@echo.
+@echo Remaining parameters ("opt!" = optional parameter):
+@echo ^ path to build directory, try . (current directory)
+@echo [flags] opt! any flags you think should be passed to build (try /a
+@echo for clean)
+@echo -WDF opt! performs a WDF build
+@echo -PREFAST opt! performs a PREFAST build
+@echo.
+@echo Special files:
+@echo The build target directory (where the DIRS or SOURCES file resides) can
+@echo contain the following files:
+@echo - %OSR_PREBUILD_SCRIPT%
+@echo Allows to include a step before the BUILD tool from the DDK is called
+@echo but after the environment for the respective DDK has been set!
+@echo - %OSR_POSTBUILD_SCRIPT%
+@echo Allows to include a step after the BUILD tool from the DDK is called,
+@echo so the environment is still available to the script.
+@echo - %OSR_SETENV_SCRIPT%
+@echo Allows to set (or override) _any_ environment variables that may exist
+@echo in the global environment. Thus you can set the base directory for the
+@echo DDK from inside this script, making your project more self-contained.
+@echo.
+@echo DDKBUILD will only handle those files which exist, so you may choose to
+@echo use none, one or multiple of these script files.
+@echo (All scripts execute inside their current directory. Consider this!)
+@echo.
+@echo Examples:
+@echo ^"%~n0 -NT4 checked .^" (for NT4 BUILD)
+@echo ^"%~n0 -WXP64 chk .^"
+@echo ^"%~n0 -WXP chk c:\projects\myproject^"
+@echo ^"%~n0 -WNET64 chk .^" (IA64 build)
+@echo ^"%~n0 -WNETAMD64 chk .^" (AMD64/EM64T build)
+@echo ^"%~n0 -WNETXP chk . -cZ -WDF^"
+@echo ^"%~n0 -WNETXP chk . -cZ -PREFAST^"
+@echo.
+@echo In order for this procedure to work correctly for each platform, it
+@echo requires an environment variable to be set up for certain platforms.
+@echo There is an auto-detection mechanism in this script, which will work best
+@echo if the DDK/WDK was installed using the normal installer (i.e. not just
+@echo copied). The auto-detection is based on the DDK/WDK for which you request
+@echo a build. Whenever you set the variable explicitly, this will take
+@echo precedence over the auto-detected path!
+@echo The environment variables are as follows:
+@echo.
+@echo %%NT4BASE%% - Set this up for ^"-NT4^" builds
+@echo %%W2KBASE%% - Set this up for ^"-W2K^" and ^"-W2K64^" builds
+@echo %%WXPBASE%% - Set this up for ^"-WXP^", ^"-WXP64^", ^"-WXP2K^" builds
+@echo %%WNETBASE%% - Set this up for ^"-WNET*^" builds
+@echo %%WLHBASE%% - Set this up for ^"-WLH*^" builds
+@echo.
+@echo %%WDF_ROOT%% must be set if attempting to do a WDF Build previous to the
+@echo Vista WDK (in later DDKs there is no need to set WDF_ROOT).
+@echo.
+@echo Path to this script:
+@echo %~f0
+@echo.
+@echo %OSR_VERSTR%
+@echo -^> report any problems to ^ or ^
+@echo.
+
+:END
+popd & endlocal & exit /b %OSR_ERRCODE%
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimerDrv/makefile b/DpcTimer_x64/DpcTimerDrv/makefile
new file mode 100644
index 0000000..98801a4
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimerDrv/mybuild.bat b/DpcTimer_x64/DpcTimerDrv/mybuild.bat
new file mode 100644
index 0000000..ecb14fe
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/mybuild.bat
@@ -0,0 +1,3 @@
+set WLHBASE=C:\WINDDK\7600.16385.0
+set WDF_ROOT=C:\WINDDK\7600.16385.0
+ddkbuild.cmd -WLH chk . -cZ -WDF
\ No newline at end of file
diff --git a/DpcTimer_x64/DpcTimerDrv/readme.txt b/DpcTimer_x64/DpcTimerDrv/readme.txt
new file mode 100644
index 0000000..f2b78db
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/readme.txt
@@ -0,0 +1,157 @@
+-----------------------
+ithurricane [http://hi.baidu.com/ithurricane]
+2010/02/04
+-----------------------
+support WDK7/VS2008
+fix Privilege Problem
+modify register source
+
+-----------------------
+bobo 2009/05/21
+-----------------------
+bug: VC6 + DDK2003 -> vc6.dsp --> # PROP Cmd_Line "ddkbuild -WNETWXP free ."
+ : ddkbuild.cmd,DDk2003ûWNETWXPWNETWXPЧͬWNETXP
+
+-----------------------
+bobo 2009/05/08
+-----------------------
+exe:
+ 1.TestAppUnicodeΪMulti-Byte(Ϊʡ,ַƴ,עдMulti-Byte),
+ TestApp.vcprojCharacterSet="1" ΪCharacterSet="2"
+ 2.TestAppغжsys(modify from MyZwDriverControl.c) òƽ́E
+ a.app,load driver
+ b.appǿƹصEʱûunload driver
+ c.app,ʱٴload driver(˵ûloadʧ),һʹdriver
+ d.˳app,unload driver
+
+ ps: MyZwDriverControl ӁEclass LoadNTDriver(copy from 0ginr.com),
+ MyZwDriverControlloadunload,ע,ɾׁE
+ class LoadNTDriverloadע᱁Eunloadɾע᱁E
+ MyZwDriverControlLockXxxDatabase.
+ 3.غжsysclass LoadNTDriver, ELoadNTDriver.h"
+
+sys:
+ DriverEntryEӡע
+ default uIoControlCode 䳁EIoCode
+ кӷҳǷҳÁE#pragma alloc_text(PAGE, DispatchXX))
+
+-----------------------
+bobo 2009/04/27
+-----------------------
+1.target osEֻѡһos
+2.DDK汾OSѡԁE
+3.fix bug : "mybuild.bat" ڵ PROJECT_MYBUILD_CMD_LINE (DDK + OS)д
+ DDK·Ĭϵģٸд鷳
+
+ DDK 2000 --- C:\\NTDDK
+ DDK XP --- C:\\WINDDK\\2600
+ DDK 2003 --- C:\\WINDDK\\3790.1830
+ WDK 6001.18002 --- C:\\WINDDK\\6001.18002
+
+4.֧WDK + win2008
+// todo : 5.check freeѡԁE(mybuild.batűEҁE "chk ." ӁE"fre .")
+
+6.һEasySysʱԶ趨û(WXPBASE,WNETBASE...)
+ Ǹע᱁EHKEY_LOCAL_MACHINE -- SOFTWARE\\Microsoft\\WINDDK 趨DDK·ġ
+ (һûװ˶DDKټӸWDK·Ҫж)
+
+ "mybuild.bat"ҲsetEʵûˡ
+
+7.űÁE忴 "ddkbuild.cmd":: Usage output
+
+-----------------------
+bobo 2009/04/23
+-----------------------
+1.MS sampleʽ"sources"
+
+-----------------------.
+bobo 2009/04/18
+-----------------------
+1. common.h, ڶexesysĹͨIOCTL
+2. console APP (for VS2005), ڲsys. ĸhello world.
+ (ֻҪDriverMonitorͿԲ)
+// todo : 3. dsp_proj.htm(VC6)EcleanҁE,VC6ʹclean.bat
+// todo : 4. MFC APP,ڲsys
+5. ע
+6.print꣬Ӧcheckfree汾build
+ #if DBG
+ #define dprintf DbgPrint
+ #else
+ #define dprintf
+ #endif
+
+ԽдԽˣeasy.....
+
+-----------------------
+bobo 2009/04/16
+-----------------------
+1.OnInitDialog()EOnChangeAuthor()
+2.OnChangeAuthor()ַ
+3.hfile.htm,cfile.htmӦԼϰ
+-----------------------
+
+bobo 2009/04/10
+-----------------------
+1.GenerateRandomStrings()new ûͷţ
+ ΪֲׁEֲ̫,64С)
+2.OnInitDialog()EOnSelectIdeType(),ʼIdeType
+ OnSelchangeDdkVersion(),ʼDDK type
+3.ddkbuild.cmd EΪ VERSION=V7.3
+4.VC6ddkbuild.batΪddkbuild.cmd
+5.OnSelchangeDdkVersion()ڵDDK2000ж
+6.VC6dsp.htmstruct.h
+
+-----------------------
+ChiChou [http://hi.baidu.com/517826104]
+2009/02/03
+-----------------------
+
+ChiChou sudamiİEׁE
+
+* BUG
+ 1.dzصBUG˳ʱûƳͼ꣬ijЩ˳ʱ
+ҵĵсE- -!
+
+ 2.ԭDDK·ʱȡעдˣ DDK
+PathòƴֱԼҵDDK·֮δе㡣
+
+ 3.ԭûмE鹤E氁EǷַôĿ¼ʱE
+ͻʱӶԷǷַcheckܡE/\|"<>*?:
+
+ 4.һBUGûڹE硰project..ʱ
+ҲļʴûаEַжеѶȡ
+ˮƽӡ(- -...)
+
+* ÁE
+ 1.ѴŪ XPBUTTON ȥ...ͼҁEٶȡ
+ 2.ȻPűͼ棬ÿ~~
+ 3.ϰԵ XP Manifest ¡
+
+* ģE
+ 1.ݸϲôEĸʽ~
+ 2.˳ѡ́EҹE濴ijжϷûȻE
+ͬ豸˽ȥ
+
+* ́Eƹ
+ 1.sudamiе鷳˳Ҫֱ̡˳
+ť
+ 2.̴֮EasySYSûôˣˡ́Eɺ˳ѡ
+ 3.ɹ̺ԴEڡߵϢ
+ 4.ɹ̺IJҲǿѡġѡԶļĿ¼
+ 5.Clean~~~
+-----------------------
+
+
+-----------------------
+sudami [sudami@163.com]
+2008/08/13
+-----------------------
+
+ VS 2005дVC 6.0ܶEöEasySYS汾(Include DIY)ֻ
+֧VC 6.0.VBGOOD̳IceBoyСͬѧVBд˸֧vs 2005
+demo.,ҲдԼĹ,ԺEٵĿЁE
+
+ ,ҪǷԼдcode,ɵcodeǰԼԸ
+...
+
+-----------------------
diff --git a/DpcTimer_x64/DpcTimerDrv/sources b/DpcTimer_x64/DpcTimerDrv/sources
new file mode 100644
index 0000000..adcd5b7
--- /dev/null
+++ b/DpcTimer_x64/DpcTimerDrv/sources
@@ -0,0 +1,9 @@
+TARGETNAME=DpcTimerDrv
+#TARGETPATH=$(BASEDIR)\lib
+TARGETPATH=obj
+TARGETTYPE=DRIVER
+
+INCLUDES=.\
+
+SOURCES=DpcTimerDrv.c
+
diff --git a/DpcTimer_x64/PCHunter64.PNG b/DpcTimer_x64/PCHunter64.PNG
new file mode 100644
index 0000000..c7a7838
Binary files /dev/null and b/DpcTimer_x64/PCHunter64.PNG differ
diff --git a/DpcTimer_x64/bin/DpcTimer.exe b/DpcTimer_x64/bin/DpcTimer.exe
new file mode 100644
index 0000000..ce9651b
Binary files /dev/null and b/DpcTimer_x64/bin/DpcTimer.exe differ
diff --git a/DpcTimer_x64/bin/DpcTimerDrv.sys b/DpcTimer_x64/bin/DpcTimerDrv.sys
new file mode 100644
index 0000000..8fde1ca
Binary files /dev/null and b/DpcTimer_x64/bin/DpcTimerDrv.sys differ