Visual C++ Directories/Inherited Properties Changes

前言

在 Visual C++ 裡頭,C++ Directories 定義了 Visual C++ 這個 IDE 要去哪些路徑下找尋 header files/library files/sources files ,在 2005/2008 裡頭,全域的設定可以在 Tools > Options > Projects and Solutions > VC++ Directories 下找到。

image

圖一、VC++ 2005 下的 VC++ Directories Dialog

這個 dialog 在 VC++ 2010 不復存在了,取而代之的是請使用者使用 property sheet 以及 per-project 的設定。

image

如果好奇為什麼做了這樣的更動,可以參考 [2] 的文章,主要是因為:

  1. 這樣全域的設定太過強大,當使用者有許多 projects 在同一台機器上 build 時,容易混淆出錯。
  2. 因為這個全域的設定檔,是存放在 %LOCALAPPDATA%\Microsoft\VisualStudio\8.0\VCComponents.dat (8.0 為 VC++ 2005,9.0 則是 2008) 這個檔案裡頭,而不是跟著每個專案檔。因此當使用者使用 source control system 時,不會把設定跟著同步到 server 上,check-out 的人也因此無法正確建置專案了。
  3. VCComponents.dat 是給 VCBuild.exe 讀的 INI 檔,而 VC++ 2010 開始改用 MSBuild.exe 來作為統一的 build utility [3] ,因此竟然要改,就連同格式一起換掉吧。

按編:這三個理由實在都很說不過去,不過既然這是 Visual C++ team 的決定,我們也只能接受了 :~

UI 變動

從 2010 之後,變動後的 VC++ Directories 不再放在 Tools > Options > Projects and Solutions > VC++ Directories ,而是以 per-project 方式存在,使用者可以:

  • 對 project 按右鍵,選擇 properties > Configuration Properties > VC++ Directories
  • 或是,從工具列:Project > <your-project-name> properties > Configuration Properties > VC++ Directories

選取 VC++ Directories 。

image

很快地,妳/你會發現,新的 dialog 跟原有的沒什麼差別,而實際上也是,只是現在的變更都是 per-project 的,不再對所有的專案有效,因此若是妳/你想將 Boost library 作為所有 VC++ project 都會使用的函式庫,就沒辦法從這裡完成;也或是,妳/你更新了 Boost 版本,每個已經使用 Boost 又想升級的 projects ,就得手動來更改。

檔案位置與格式變化

說完了使用上的變動,接著是檔案位置的更動,存放的位置從:

%LOCALAPPDATA%\Microsoft\VisualStudio\8.0\VCComponents.dat

換到了:

%LOCALAPPDATA%\Microsoft\MSBuild\v4.0\

下,並且以 Microsoft.Cpp.<Platform>.user 命名:

  • Microsoft.Cpp.ARM.user
  • Microsoft.Cpp.Itanium.user
  • Microsoft.Cpp.Win32.user
  • Microsoft.Cpp.x64.user

image

新的檔案格式稱作:Property sheet ,附檔名 props 。有了這個檔案,我們還是有機會可以做到 2005 & 2008 時的全域設定。先前提到了:為了迎接 MSBuild 的來臨,VC++ 將 INI 格式變成了 XML 格式,所以客製化上還是很簡單的,任選一個 platform 的檔案打開:

image

所以一種修改方式,就是直接用編輯器修改 XML ,看想修改哪些就可以改,值得一提的是,以往在 2005 & 2008 裡頭,路徑名不可以是 Visual C++ 裡頭的 Macro ,現在反倒是可以了,因為 IDE 是將檔案中的值讀入後才做解析。另外一種方式則是透過 Visual C++ 內建的 Property Manager 修改,我們放到下一節介紹。

Inherited Values

wdk803

當 Visual C++ 將 property sheet 讀入後,會當做 Inherited values ,對於當前 project 來說,是不可編輯的,我們必須繞到 props 檔去,或是使用 property manager 編輯。property manager 可以從工具列 > View > Property Manager 找到:

image

叫起 Property Manager 後,可以看到目前 project configuration 所涵蓋的 platform 的設定。 Double click 後,可以看到跳出一個視窗,

image

跳出來的視窗長得很像 project properties ,不過仔細看會發現 Configuration 和 Platform 已經被鎖死成對應的 property sheet 檔所代表的設定,接著,直接編輯,然後存檔,這樣就完成了修改全域 property sheet 了。

VC++ 2010 & VC++2012

值得注意的是,property sheet 放在 MSBuild 的 local app data 下,而目前 2010 和 2012 所使用的 MSBuild 都是 4.0 [4],因此一旦我們修改了 property sheet ,可是會同時影響到 2010 跟 2012 的 ... Orz ...

Reference

  1. Inherited Properties and Property Sheets: http://blogs.msdn.com/b/vsproject/archive/2009/06/23/inherited-properties-and-property-sheets.aspx
  2. VC++ Directories: http://blogs.msdn.com/b/vsproject/archive/2009/07/07/vc-directories.aspx
  3. VCBuild vs. C++ MSBuild on the Command Line: http://blogs.msdn.com/b/vcblog/archive/2010/01/11/vcbuild-vs-c-msbuild-on-the-command-line.aspx
  4. MSBuild Toolset: http://msdn.microsoft.com/en-us/library/bb383796.aspx

VC++ 2012 Can't Build Driver Project

這幾天終於趁著聽課的空檔,把電腦裝了 VC++ 2012 ,這版的一大特色:整合了 device driver 的開發。很快地試玩了一下它的 project wizard :

wdk801

結果,很不幸地失敗 ...

1>C:\Program Files (x86)\Windows Kits\8.0\Include\KM\wdm.h(10920): fatal error C1003: error count exceeds 100; stopping compilation

再看一下 Error list:

Error    1    error C2220: warning treated as error - no 'object' file generated    C:\Program Files (x86)\Windows Kits\8.0\Include\shared\sal.h    2884
Error    4    error C2054: expected '(' to follow '_IRQL_requires_same_'    C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ntdef.h    1897
Error    5    error C2085: 'EXCEPTION_ROUTINE' : not in formal parameter list    C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ntdef.h    1903
Error    6    error C2085: 'EXCEPTION_ROUTINE' : not in formal parameter list    C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ntdef.h    1905
Error    7    error C2143: syntax error : missing ';' before '*'    C:\Program Files (x86)\Windows Kits\8.0\Include\shared\ntdef.h    1905
Error    8    error C2143: syntax error : missing ')' before 'constant'    C:\Program Files (x86)\Windows Kits\8.0\Include\KM\wdm.h    10384
Error    9    error C2143: syntax error : missing '{' before 'constant'    C:\Program Files (x86)\Windows Kits\8.0\Include\KM\wdm.h    10384
Error    10    error C2059: syntax error : '<Unknown>'    C:\Program Files (x86)\Windows Kits\8.0\Include\KM\wdm.h    10384

真的是很 ooxx 。問題都是發生在 sal.h, ntdef.h wdm.h 等等基本的 header files 裡。

這類的問題通常是發生在 include 了錯誤的 header files ,所以回頭檢視 solution property : Project >  Properties > Configuration Properties > VC++ Directories 。

image

include directories 多了很多路徑,其他像是 Executable Directories 、Library Directories 也有一樣的問題。嗯嗯,VC++ 2012 匯入了電腦上其他版本 VC++ 的設定,可能的原因之一:安裝完 2012 、第一次啟動時,我允許了 2012 去找尋舊版本的設定並匯入所導致。再點開 Include Directories 看一下:

image

發現這些多餘的路徑都是來自 Inherited values 。這裡,我試了兩種解決方式:

  1. 解法一
    取消 Inherit from parent or project defaults ,然後重新把需要的路徑一個一個加回去,也就是手動把
    $(ProjectDir)、$(CRT_INC_PATH)、$(ddk_INC_PATH)、$(KIT_SHARED_INC_PATH) 加上去。手動作這件事除了麻煩外,還只能用在這個 project 上,也就是一旦我開了新的 driver solution 或是在當下 solution 下新增新的 driver project 都得重做一次。
  2. 解法二
    比較一勞永逸, VC++ 把這個 Inherited Values 定義在 C:\Users\<user-name>\AppData\Local\Microsoft\MSBuild\v4.0 下的檔案裡頭,檔案是根據不同 configuration 而命名:
    Microsoft.Cpp.ARM.user.props
    Microsoft.Cpp.Itanium.user.props
    Microsoft.Cpp.Win32.user.props
    Microsoft.Cpp.x64.user.props
    *.props 是 XML 格式,把不用的 path 都清除乾淨,只留下 default value 就可以了。
    <?xml version="1.0" encoding="utf-8"?>
    <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <ExecutablePath>$(ExecutablePath)</ExecutablePath>
        <IncludePath>$(IncludePath)</IncludePath>
        <ReferencePath>$(ReferencePath)</ReferencePath>
        <LibraryPath>$(LibraryPath)</LibraryPath>
        <SourcePath>$(SourcePath)</SourcePath>
        <ExcludePath>$(ExcludePath)</ExcludePath>
      </PropertyGroup>
    </Project>

    這個方法是比較一勞永逸,不過有個大缺點:不同版本的 Visual C++ 會共用這個檔案。像我的電腦修改了後, VC++ 2010 的 VC++ project 的預設值也會受到影響,但已經產生的、既有 project 則不受影響,算是不幸中的大幸。

Facebook App -- Getting Started with Apps on Facebook + Heroku

Facebook App 時下分成三類:

  1. Facebook for Websites
    這類的 apps ,可以讓妳/你使用 Facebook 提供的 social plugins 來幫自己的網站加分,像是在你的網頁中加入"讚"按鈕、讓使用者使用 Facebook 帳號登入、存取使用者在 Facebook 的資料。
  2. Mobile Apps
    Facebook 分別在 iOS 和 Android 上提供 Object-C 和 Java 版本的 SDK ,來讓開發者可以提供 native apps。其他還有 PHP 和 JavaScript 可以選擇。
  3. Apps on Facebook
    把我們的 apps 整合在 Facebook 上,使用者必須透過 Facebook 來存取我們的 apps , Facebook 提供適當的頁面,並把我們的 apps 導入其中的 iframe 裡頭。

特別要注意的是, Facebook 只提供我們使用 Facebook 的 social platform ,但它並不提供 code hosting ,因此開發 Apps on Facebook 需要自己準備 web server 或是第三方的 web hosting ,運氣不錯的是,Facebook 和 Heroku 有正式的合作,因此若是找不到代管服務或是懶得自己架站的開發者,可以先使用 Heroku 來試試看。

Apps on Facebook

步驟一

登入 https://developers.facebook.com/apps 。第一次登入時, Facebook 會詢問您相關的 permission ,選 allow 就可以。之後就會看到下面的畫面,點選 Create New App

FB_App_1

步驟二

image

  • App Name: 輸入妳/你的 app name 。
  • App Namespace: 其實就是我們 app 的 URL 。它會附加在 http://apps.facebook.com 之後,所以必須是個 unique name ,另外還有一些名規則。 輸入完後 Dialog 會幫你 check ,若是失敗也會報錯。
  • Web Hosting: 目前 Facebook 只跟 Heroku 官方合作,所以要是我們沒有自己的 hosting server ,也可以考慮一下 Heroku ,它支援 PHP 、 Python 、 JavaScript 、 Ruby 。

步驟三

跟 Facebook 說一下,妳/你不是機器人吧~

步驟四

image

選擇一下妳/你想用的開發語言。

image

若是事先沒有 Heroku 帳號也不用擔心,透過這個步驟填入 email 就會幫妳/你申請。

步驟五

image

看到這個 dialog 出現,就恭喜妳/你成功囉。

步驟六

當妳/你點下 Go To App 後,瀏覽頁會被導到 Heroku 代管的 app page 去,以這邊的例子會是:http://evening-plateau-9255.herokuapp.com

FB_App_3

開發

步驟一、找到對應的 Git repository

若是之前沒有 Heroku 的帳號,當完成上面的步驟後,Heroku 會寄一封啟動信到步驟四的信箱去。或是之前已經有 Heroku 帳號,可以直接到 https://dashboard.heroku.com/apps? 去看一下,會發現多了一個 evening-plateau-9255 ,點進去後,請找 Settings > Info > Git URL ,以本文的例子, Heroku 配給我們的 git url 是 git@heroku.com:evening-plateau-9255.git

步驟二、下載 Herolu toolbelt

toolbelt 是 cmd line 工具包,主要包含了 Heroku 環境初始化工具、app 的 local 模擬和 Git 。

步驟三、初始化環境

安裝完 toolbelt 後,它應該已經被加入到環境變數裡頭。這時,請準備一個新資料夾來當做 working folder ,並使用 cmd.exe 切到該 folder 下,執行:

heroku login

image

步驟四、Clone 一份來改吧

還記得自己的 app git URL 嗎?

git clone git@heroku.com:your_app_name_in_heroku.git -o heroku

到這裡,妳/你已經可以開始做些了,若是不熟悉 Git ,可以參考下面指令把你的修改上傳到 server 上去:

git commit -am "commit message"
git push heroku master

Reference

  1. Canvas Tutorial: http://developers.facebook.com/docs/appsonfacebook/tutorial/
  2. Getting Started with Your Facebook App on Heroku: https://devcenter.heroku.com/articles/facebook

Windows Debugging 2 – Kernel Debugging with WinDbg and VMware

Windows Vista 之後已經不再將開機選項儲存於 boot.ini 中,而是改以 BCD (Boot Configuration Data) 儲存,因此以前透過編輯 boot.ini 啟動 Windows kernel debugging 的方法也得更新一下。這裡我們透過 bcdedit.exe 來編輯 BCD ,讓 Windows 啟動後可以進入 debug mode 。

VMware 設定

Debuggee 部分,和以前一樣使用 named piped 來替 guest OS 模擬 serial port (COM port)。

  1. 進入 guest OS 設定。 com port
  2. 新增硬體。
    com port 2
  3. 選擇 Serial Port 裝置。
    com port 3
  4. 選擇 named pipe 來模擬我們的 serial port。
    com port 4
  5. 替 named pipe 取一個名字,這個名字等會會被 WinDbg 使用。
    com port 5
  6. 最後別忘了把 Yield CPU on Poll 選項勾起。
    com port 6
  7. 完成新增後,請留意 VMware 替我們新增的 Serial Port 的編號,以上圖為例是:Serial Port 2 

Windows Boot 設定

  1. 使用 administrator 權限開啟一個 cmd。
    start cmd
  2. 透過 BCDEdit 編輯開機選項,使用 COM port (serial port)來做為 debugger 和 debuggee 間的溝通,debugport 的編號請根據 VMware 的 Serial Port 設定而定:
    bcdedit /dbgsettings serial debugport:2
  3. 複製現有的開機選項到 DebugEntr:
    bcdedit /copy {current} /d DebugEntry
    執行完該指令後,會出現一個 ID ,代表我們要複製出來的開機選項,該 ID 在每台電腦上都不太一樣。
  4. 調整開機選樣的順序:
    bcdedit /displayorder {current} {ID}
  5. 打開 debug 選項:
    bcdedit /debug {ID} ON
  6. 設定成預設開機選項:
    bcdedit /default {ID}
    bcdedit edit

 

Enable Debug Print

Vista之後,DbgPrintEx()、vDbgPrintEx()、vDbgPrintExWithPrefix()、KdPrintEx() 等選擇性的輸出函式預設是關閉的,要啟動的話,需要到 registry 上設定對應的 log level [3]:

到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Debug Print Filter 下新增 DEFAULT=dword:0000ffff
實際數值,依照需求而定,0000ffff 足以應付大多數用途。

Debug Print Filter

使用

在 bcdedit 設定完成後,重開機,便會看到新的開機選項 DebugEntry:

boot 1

選擇 DebugEntry 後,我們便可以在 debugger 的機器上的 cmd 執行下面指令來進行 kernel debugging,com_1 就是我們當初在 VMware guest OS 裡頭設定的名字:

windbg -b -k com:pipe,port=\\.\pipe\com_1,resets=0

停用驅動程式簽章增強(Disable Driver Signature Enforcement)

Vista 之後的 64-bit OS ,Microsoft 都會要求 drivers 必須有 WHQL 的認證才能啟動。這對於一般使用者來說可能沒有影響,但對於有在開發、測試 drivers 的人就會是個問題。

最簡單的方式是,開機時,使用 F8 進入進階模式:
boot 1
並選擇(停用驅動程式簽章增強)Disable Driver Signature Enforcement。
boot 2

Test Signing

若是 drivers 有 test sign ,那麼我們還可以使用 BCDEdit 來允許 testing sign driver 的載入[4]:
bcdedit /set TESTSIGNING ON
設定完成後,需要重開機。

要驗證 test sign 是否成功,可以使用 bcdedit 檢查,或是觀察桌面右下角的文字說明:

test signing

Reference

  1. Boot Parameters to Enable Debugging
    http://msdn.microsoft.com/en-us/library/windows/hardware/ff542279%28v=vs.85%29.aspx
  2. Kernel Debugging in Windows Vista
    http://msdn.microsoft.com/en-us/windows/hardware/gg487520
  3. Reading and Filtering Debugging Messages
    http://msdn.microsoft.com/en-us/library/windows/hardware/ff551519%28v=vs.85%29.aspx
  4. The TESTSIGNING Boot Configuration Option
    http://msdn.microsoft.com/en-us/library/windows/hardware/ff553484%28v=vs.85%29.aspx

See Also

  1. Windows Debugging – Kernel Debugging with WinDbg and VMware
    http://keikoblog.blogspot.com/2009/03/windows-debugging-kernel-debugging-with.html

MiniFilter InstanceSetupCallback is not called?

一般來說,MiniFilter 的 InstanceSetupCallback 會在 filter manager 把 minifilter attache 到 volume 後呼叫。如果沒有的話,可以檢查一下 minifilter 的 INF 是否把 instance fla...