2009年2月17日 星期二

Unlocker .NET

下載 Unlocker.NET.dll

軟體名稱:Unlocker.NET.dll
版本:v 1.0
軟體作者:cuteofdragon
軟體授權:學術使用免費軟體
軟體類型:Library
軟體開發:Visual Studio .NET 2005 C#
發佈時間:2009/02/18

簡介
Unlocker .NET 是一個純粹採用 .NET C# 撰寫的 dll,目的為處理在 Windows 檔案系統下強制關閉正在被其它程序使用的檔案 Handle,使目前正在處理的程序可以對該檔案進行讀取或刪除等動作。

原理說明
Unlocker .NET 主要使用到 Microsoft 未公開文件的 ntdll.dll 裡面的函式,透過 .NET Interop 技術呼叫原生 Win32 函式,並揭露如何將 C-Style 函式指標轉換成 .NET C# delegate 型式。以下說明相關技術實作。

所使用到的 ntdll.dll 函式指標原型宣告如下:
typedef DWORD (WINAPI *PNtQueryObject)( HANDLE, DWORD, VOID*, DWORD, VOID* );
typedef DWORD (WINAPI *PNtQuerySystemInformation)( DWORD, VOID*, DWORD, ULONG* );
typedef DWORD (WINAPI *PNtQueryInformationFile)(HANDLE, PVOID, PVOID, DWORD, DWORD );

載入函式指標方法:
PNtQueryObject NtQueryObject;
PNtQuerySystemInformation NtQuerySystemInformation;
PNtQueryInformationFile NtQueryInformationFile;

NtQueryObject = (PNtQueryObject) GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ), _T("NtQueryObject") );
NtQuerySystemInformation = (PNtQuerySystemInformation) GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ), _T("NtQuerySystemInformation") );
NtQueryInformationFile = (PNtQueryInformationFile) GetProcAddress( GetModuleHandle( _T( "ntdll.dll" ) ), _T("NtQueryInformationFile") );

轉換後的 C# delegate 原型宣告如下:
delegate uint NtQueryObjectDelegate(IntPtr hHandle, uint dw1, [MarshalAs(UnmanagedType.LPArray)] byte[] buffer, uint bufferLength, ref uint needLength);
delegate uint NtQuerySystemInformationDelegate(uint dw1, IntPtr systemHandleInformation, uint bufferSize, ref uint needLength);
delegate uint NtQueryInformationFileDelegate(IntPtr hHandle, uint[] iob, IntPtr buffer, uint bufferSize, uint dw2);

delegate 取得 C-Style 函式指標方法:
IntPtr ntQueryObjectPtr = IntPtr.Zero;
IntPtr ntQuerySystemInformationPtr = IntPtr.Zero;
IntPtr ntQueryInformationFilePtr = IntPtr.Zero;

NtQueryObjectDelegate ntQueryObjectDelegate = null;
NtQuerySystemInformationDelegate ntQuerySystemInformationDelegate = null;
NtQueryInformationFileDelegate ntQueryInformationFileDelegate = null;

ntQueryObjectPtr = NativeMethod.GetProcAddress(NativeMethod.GetModuleHandle("ntdll.dll"), "NtQueryObject");
ntQuerySystemInformationPtr = NativeMethod.GetProcAddress(NativeMethod.GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");
ntQueryInformationFilePtr = NativeMethod.GetProcAddress(NativeMethod.GetModuleHandle("ntdll.dll"), "NtQueryInformationFile");

ntQueryObjectDelegate = (NtQueryObjectDelegate)Marshal.GetDelegateForFunctionPointer(ntQueryObjectPtr, typeof(NtQueryObjectDelegate));
ntQuerySystemInformationDelegate = (NtQuerySystemInformationDelegate)Marshal.GetDelegateForFunctionPointer(ntQuerySystemInformationPtr, typeof(NtQuerySystemInformationDelegate));
ntQueryInformationFileDelegate = (NtQueryInformationFileDelegate)Marshal.GetDelegateForFunctionPointer(ntQueryInformationFilePtr, typeof(NtQueryInformationFileDelegate));

以 .NET C# 方法進行呼叫 delegate
public uint NtQueryObject(IntPtr hHandle, uint dw1, byte[] buffer, uint bufferSize, ref uint needLength)
{
return ntQueryObjectDelegate.Invoke(hHandle, dw1, buffer, bufferSize, ref needLength);
}

public uint NtQuerySystemInformation(uint dw1, IntPtr systemHandleInformation, uint bufferSize, ref uint needLength)
{
return ntQuerySystemInformationDelegate.Invoke(dw1, systemHandleInformation, bufferSize, ref needLength);
}

public uint NtQueryInformationFile(IntPtr hHandle, uint[] iob, IntPtr buffer, uint bufferSize, uint dw2)
{
return ntQueryInformationFileDelegate.Invoke(hHandle, iob, buffer, bufferSize, dw2);
}

Unlocker .NET 如何取得鎖住檔案的程序 Handle
1. 透過 NtQuerySystemInformation 方法取得所有系統中使用的 Handle
2. 透過 NtQueryObject 方法可獲得系統的 Handle 是屬於那一類型,包括 Process、Thread、File 等
3. 透過 NtQueryObject 方法可取得任一 File Handle 被那一個程序使用中

Unlocker .NET 強制關閉 File Handle 原理
1. 首先要 Enable DEBUG privilege
2. 透過 OpenProcess Win32 API 取得鎖住檔案的程序 Handle
3. 透過 CreateRemoteThread Win32 API 呼叫 CloseHandle Win32 API

如何使用 Unlocker.NET.dll
下載並加入 Unlocker.NET.dll 參考

using Unlocker.NET;
class Program
{
static void Main(string[] args)
{
// C:\01.bmp 為被鎖住的檔案名稱
if (Unlocker.CloseFileHandle(@"C:\01.bmp"))
{
Console.WriteLine("成功關閉檔案");
}
else
{
Console.WriteLine("關閉檔案失敗");
}
Console.ReadLine();
}
}

參考網址:http://www.codeguru.com/Cpp/W-P/files/fileio/article.php/c1287/

2009年1月15日 星期四

How to pass the RegisterKey to RegOverridePredefKey function

說明:
RegisterKey 是一個 .NET managed物件,RegOverridePredefKey 是一個原生Win32的函式呼叫,該函數主要用途在允許將一個預定義的註冊表項映射到另一個註冊表項。RegOverridePredefKey 的使用時機請連結參考網址。本文主旨在說明如何不使用原生自訂的Win32的函式庫而使用.NET managed達到如參考網址相同功能。

RegOverridePredefKey 原始宣告:
LONG RegOverridePredefKey(HKEY hKey, HKEY hNewHKey);

RegOverridePredefKey .NET P/Invoke 宣告:
[DllImport("advapi32.dll")]
public static extern long RegOverridePredefKey(IntPtr key, IntPtr newKey);

解決方法:
定義一個轉換方法 ;fieldInfo.GetValue 在 .NET 2.0 無法直接轉型成 IntPtr,其在取得 hkey 屬性時的型別為 Microsoft.Win32.SafeHandles.RegistrySafeHandle,繼承自System.Runtime.InteropServices.SafeHandle。
public static IntPtr GetRegistryHandle(RegistryKey registryKey)
{
Type type = registryKey.GetType();
FieldInfo fieldInfo = type.GetField("hkey", BindingFlags.Instance BindingFlags.NonPublic);
return ((SafeHandle)fieldInfo.GetValue(registryKey)).DangerousGetHandle();
}

附註:
RegOverridePredefKey 的使用時機之一是在OpenFileDialog自定義左邊PlacesBar,在.NET 2.0 sp1之後,OpenFileDialog已支援 CustomPlaces的集合屬性。

參考網址:http://msdn.microsoft.com/zh-cn/library/aa663661.aspx

2008年12月25日 星期四

電腦上沒有安裝需要的音訊轉碼器 Windows Media Player 無法播放

在 Acer Aspire 4920 筆記型電腦使用 Microsoft Windows XP 作業系統時,已經安裝成功 Realtek High Definition Audio 音效裝置,開啟 Windows Media Player 欲播放檔案時卻出現「由於您的電腦上沒有安裝需要的音訊轉碼器,Windows Media Player 無法播放、燒錄、擷取或同步檔案。」的訊息。

問題原因:
不知安裝或移除什麼程式之後發生此問題,且右下角喇叭圖示也消失了,但使用 KMP Player 或 其它播放軟體仍然可以正常播放檔案。

解決方式:
1. 安裝 K Lite Mega Codec Pack,在安裝時勾選 Reset all setting to their defaults 和 Create file associations for Windows Media Player;安裝時會檢查和修正相關音訊轉碼等登錄檔錯誤問題。
2. 在控制台聲音及音訊裝置確定所有裝置設定為 Realtek HD Audio Input/Output 等裝置,並勾選只使用預設裝置(此步驟可讓右下角喇叭圖示正常顯示)。
3. 開啟 Windows Media Player -> 工具 -> 選項 -> 播放程式,勾選自動下載轉碼器。

2008年11月6日 星期四

ClickOnce 無法下載 manifest

在 Microsoft Windows Server 2003 做用 Visual Studio 2005 部署 ClickOnce 完成後,使用瀏覽器連結部署網頁啟動程式發生錯誤時,詳細內容中的錯誤摘要指出:遠端伺服器傳回一個錯誤: (404) 找不到。

問題原因:
Windows Server 2003 IIS 伺服器會自動阻檔未知的副檔名,就算安裝 .NET Framework 2.0 後設定 web.config,還是無法下載 manifest。

解決方式:
在 網際網路資訊服務(IIS)管理員點擊滑鼠右鍵->內容->MIME類型,新增下列副檔名:
.application application/x-ms-application
.manifest application/x-ms-application
.deploy application/octet-stream

2008年4月14日 星期一

iwpdgina.dll Fast User Switching Compatibility

問題描述:

在 Windows XP 安裝 Intel 無線網路卡 PROSet 進階管理工具,例如:Intel PRO/Wireless LAN 2100 3B Mini PCI Adapter,會發生原本 Windows XP 歡迎畫面變更為傳統的登入畫面,而且無法快速切換使用者;而這項功能可透過控制台->使用者帳戶->變更使用者登入或登出方式進行變更,但是會發生如下無法變更訊息對話框:

"A recently installed program has disabled the Welcome screen and Fast UserSwitching. To restore these features, you must unistall the program. Thefollowing name might help you identify the program that made the change:iwpdgina.dll"

"一個最近安裝的程序已停用歡迎螢幕和快速切換。你必須卸載該程序以恢復這些功能。下列檔案可以幫助你識別該程序多做的修改:iwpdgina.dll"

目前解決方式:

一般作法是移除 Intel 無線網路卡 PROSet 進階管理工具,或是在安裝時不選擇單次簽入功能組選項;然而有些情況下不得不使用 PROSet,例如:需要連接 Cisco CKIP 安全加密的無線網路環境,或是在不選擇單次簽入功能組選項仍然鎖住 Windows XP 歡迎畫面。

建議解決方式:

如果選擇單次簽入功能組選項時會造成系統不正常啟動,則不勾選,有時候甚至只能登入安全模式。對於 Intel 無線網路卡 PROSet 進階管理工具造成鎖住 Windows XP 歡迎畫面的原因是因為登錄註冊表
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]
裡面設定了
"GinaDLL"="iwpdgina.dll"
因此,將此機碼刪除即可恢復 Windows XP 歡迎畫面。此方式在安全模式下亦可執行(若要移除 PROSet 在安全模式下是無法執行的)。

2008年3月23日 星期日

Microsoft Windows Mobile ActiveSync Installer

Microsoft.WindowsMobile.ActiveSync.dll
專案測試

軟體名稱:Microsoft.WindowsMobile.ActiveSync.dll
版本:v 1.0
軟體作者:cuteofdragon
軟體授權:學術授權免費軟體
發佈時間:2008/03/23

簡介
Microsoft WindowsMobile ActiveSync 使用在開發 Windows Mobile-based 的應用程式,包括早期的 Pocket PC 2003、Windows CE 5.0、Windows Mobile 5 和目前 Windows Mobile 6 的行動裝置,都必須透過 ActiveSync 進行應用程式的部署;當然,如果在已安裝 Visual Studio .NET 2005 的電腦情況下,可以直接點選部署的選單將程式直接透過 ActiveSync DMA 連線傳送到指定的行動裝置上,但是在沒有安裝 Visual Studio .NET 2005 的電腦時,傳統的方法是透過 ActiveSync 在檔案總案建立的行動裝置將編譯完成的執行檔複製到裝置裡面的 ProgramFiles 資料夾內。


說明
Microsoft.WindowsMobile.ActiveSync.dll 為一可解決在沒有安裝 Visual Studio .NET 2005 的電腦進行行動裝置自動化安裝部署的 Installer 類別函式庫,換句話說,透過此 Installer 即可在專案開發時期設定完成 Setup 相關指令碼,將傳統上所有需要的執行相關檔案封裝成安裝檔,之後當電腦和行動裝置透過 ActiveSync 連接時,執行安裝檔即可全自動地在連接 ActiveSync 的行動裝置上進行安裝,並在程式集產生捷徑,就如同一般行動裝置上的程式。

步驟
1. 下載 Microsoft.WindowsMobile.ActiveSync.dll 和專案測試檔。
2. 建立一個行動裝置 DeviceApplication1。
3. 建立一個行動裝置 SmartDeviceCab1。
4. 建立一個一般電腦 Setup1。
5. 在 SmartDeviceCab1 增加 Project Outputs DeviceApplication1。
6. 在 Setup1 增加 SmartDeviceCab1 和 組件 Microsoft.WindowsMobile.ActiveSync.dll。
7. 在 Setup1 Custom Action 增加 Microsoft.WindowsMobile.ActiveSync.dll,並設定CustomActionData = /ActiveSyncProductName="SmartDeviceCab1"。
8. 完成,如下圖所示。