Archive for the Win Driver Category

Note: Previous releases of the WDK/DDK

Posted in Win Driver on 2012 年 04 月 10 日 by Kun-Yi

Update: currently MS has been close the program, so the link is invalid.

https://connect.microsoft.com/site148/Downloads/DownloadDetails.aspx?DownloadID=21028, need join Microsoft Connect project!

current provide the below DDK/WDK

GRMWDK_EN_7600 – WDK for Windows 7

6001.18002 – WDK for Windows Server 2008, Vista Sp1

6000 – WDK for Vista

1830 – DDK for Windows Server 2003 SP1

winddk.rtm.iso – DDK for Windows 2000

Note: 剖析 ACPIEC Part II – AddDevice & Create Device Object

Posted in ACPI, Win Driver on 2010 年 07 月 08 日 by Kun-Yi

還是把 AcpiEcAddDevice 拿出來, 基本做的就一般 Function/Filter driver要做的事!
AddDevice會由PNP Manager 傳進兩個Parameters, 一個是 本身的Driver Object 另一個是Physical Device Object
一開始會按照標準的Function Driver 一般去建立 FDO (Function Device Object), 這是透過AcpiEcCreateFdo() 來實現的

在AcpiEcCreateFdo()內就是簡單的呼叫 IoCreateDevice() 去Create該FDO, 取得FDO 之後, 將其參數初始化與建立同步物件

取得FDO後, 透過 IoAttachDeviceToDeviceStack() 把FDO掛上

NTSTATUS
AcpiEcAddDevice(
IN PDRIVER_OBJECT   DriverObject,
IN PDEVICE_OBJECT   Pdo
)

/*++

Routine Description:

This routine creates functional device objects for each AcpiEc controller in the
system and attaches them to the physical device objects for the controllers

Arguments:

DriverObject       – a pointer to the object for this driver
PDO                  – a pointer to where the FDO is placed

Return Value:

Status from device creation and initialization

–*/

{
PDEVICE_OBJECT  fdo = NULL;
PDEVICE_OBJECT  ownerDevice = NULL;
PDEVICE_OBJECT  lowerDevice = NULL;
PECDATA         EcData;
NTSTATUS        status;

PAGED_CODE();

EcPrint(EC_LOW, (“AcpiEcAddDevice: Entered with pdo %xn", Pdo));

if (Pdo == NULL) {

//
// Have we been asked to do detection on our own?
// if so just return no more devices
//

EcPrint(EC_LOW, (“AcpiEcAddDevice – asked to do detectionn"));
return STATUS_NO_MORE_ENTRIES;
}

//
// Create and initialize the new functional device object
//

status = AcpiEcCreateFdo(DriverObject, &fdo);

if (!NT_SUCCESS(status)) {

EcPrint(EC_LOW, (“AcpiEcAddDevice – error creating Fdon"));
return status;
}

//
// Layer our FDO on top of the PDO
//

lowerDevice = IoAttachDeviceToDeviceStack(fdo,Pdo);

//
// No status. Do the best we can.
//
ASSERT(lowerDevice);

EcData = fdo->DeviceExtension;
EcData->LowerDeviceObject = lowerDevice;
EcData->Pdo = Pdo;

//
// Allocate and hold an IRP for Query notifications, and miscellaneous
//
EcData->IrpSize         = IoSizeOfIrp (EcData->LowerDeviceObject->StackSize);
EcData->QueryRequest    = IoAllocateIrp (EcData->LowerDeviceObject->StackSize, FALSE);
EcData->MiscRequest     = IoAllocateIrp (EcData->LowerDeviceObject->StackSize, FALSE);

if ((!EcData->QueryRequest) || (!EcData->MiscRequest)) {
//
// NOTE: This failure case and other failure cases below should do
// cleanup of all previous allocations, etc performed in this function.
//

EcPrint(EC_ERROR, (“AcpiEcAddDevice: Couldn’t allocate Irpn"));
return STATUS_INSUFFICIENT_RESOURCES;
}

//
// Link this fdo to the list of fdo’s managed by the driver
// (Probably overkill since there will be only one FDO)
//
//
EcPrint(EC_LOW, (“AcpiEcAddDevice: linking fdo to listn"));
EcData->NextFdo = FdoList;
InterlockedExchangePointer((PVOID *) &FdoList, fdo);

//
// Get the GPE vector assigned to this device
//

status = AcpiEcGetGpeVector (EcData);
if (!NT_SUCCESS(status)) {

EcPrint(EC_LOW, (“AcpiEcAddDevice: Could not get GPE vector, status = %Lxn", status));
return status;
}

//
// Get the direct-call ACPI interfaces.
//

status = AcpiEcGetAcpiInterfaces (EcData);
if (!NT_SUCCESS(status)) {

EcPrint(EC_LOW, (“AcpiEcAddDevice: Could not get ACPI driver interfaces, status = %Lxn", status));
return status;
}

//
// Final flags
//

fdo->Flags &= ~DO_DEVICE_INITIALIZING;
fdo->Flags |= DO_POWER_PAGABLE;             // Don’t want power Irps at irql 2

return STATUS_SUCCESS;
}

 

NTSTATUS
AcpiEcCreateFdo(
IN PDRIVER_OBJECT   DriverObject,
OUT PDEVICE_OBJECT  *NewDeviceObject
)

/*++

Routine Description:

This routine will create and initialize a functional device object to
be attached to a Embedded controller PDO.

Arguments:

DriverObject – a pointer to the driver object this is created under
DeviceObject – a location to store the pointer to the new device object

Return Value:

STATUS_SUCCESS if everything was successful
reason for failure otherwise

–*/

{
UNICODE_STRING  unicodeString;
PDEVICE_OBJECT  deviceObject;
NTSTATUS        Status;
PECDATA         EcData;

PAGED_CODE();

EcPrint(EC_LOW, (“AcpiEcCreateFdo: Entryn") );

RtlInitUnicodeString(&unicodeString, L"\Device\ACPIEC");

Status = IoCreateDevice(
DriverObject,
sizeof (ECDATA),
&unicodeString,
FILE_DEVICE_UNKNOWN,    // DeviceType
0,
FALSE,
&deviceObject
);

if (Status != STATUS_SUCCESS) {
EcPrint(EC_LOW, (“AcpiEcCreateFdo: unable to create device object: %Xn", Status));
return(Status);
}

deviceObject->Flags |= DO_BUFFERED_IO;
deviceObject->StackSize = 1;

//
// Initialize EC device extension data
//

EcData = (PECDATA) deviceObject->DeviceExtension;
EcData->DeviceObject        = deviceObject;
EcData->DeviceState         = EC_DEVICE_WORKING;
EcData->QueryState          = EC_QUERY_IDLE;
EcData->IoState             = EC_IO_NONE;
EcData->IsStarted           = FALSE;
EcData->MaxBurstStall       = 50;
EcData->MaxNonBurstStall    = 10;
EcData->InterruptEnabled    = TRUE;

//
// Initialize EC global synchronization objects
//

InitializeListHead (&EcData->WorkQueue);
KeInitializeEvent (&EcData->Unload, NotificationEvent, FALSE);
KeInitializeSpinLock (&EcData->Lock);

*NewDeviceObject = deviceObject;
return STATUS_SUCCESS;

}

 

Note: 剖析ACPIEC Part I

Posted in ACPI, Win Driver on 2010 年 07 月 06 日 by Kun-Yi

在 Windows 平台上, 從 Win98 就開始引入 ACPI and ACPIEC driver stack, 好玩的是就Microsoft 有提供的source code(早期的DDK有附, Win2000) 看來, 實際上 ACPIEC.Sys 的Source code 應該是Intel 的 Bob Moore 所撰寫, 而我現在實測編譯出來的binary size 為 12.1KB(12,416Byte) 比XP Sp3還大一點, 底下是Build log, 研判應該是編譯參數問題, 有 9成的把握該Driver 在 XP 還是依據這個原始的Source, 要注意的是這個source 並不在 6001.18001內, 這是從舊的DDK內取出的!(Update: http://www.osronline.com/showthread.cfm?link=150332 跟據這個討論串中由 Jake Oshins/MSFT 指出從Vista開始已經將 ACPIEC一些功能直接整進 ACPI.SYS了)

BUILD: Computing Include file dependencies:
BUILD: Examining c:winddk6001.18001srcwdmacpiecec directory for files to compile.
skipping post pass 0 command
Compiling and Linking c:winddk6001.18001srcwdmacpiecec *************
‘nmake.exe /nologo BUILDMSG=Stop. -i BUILD_PASS=PASS2 LINKONLY=1 NOPASS0=1 MAKEDIR_RELATIVE_TO_BASEDIR=srcwdmacpiecec’
c:winddk6001.18001srcwdmacpiecec: TARGETPATH is obj
BUILDMSG: _NT_TARGET_VERSION SET TO WINXP
c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386echo.msg not found
Microsoft (R) Windows (R) Resource Compiler Version 6.0.5724.0
Copyright (C) Microsoft Corporation.  All rights reserved.
cl.exe @c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386cl.rsp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.278 for 80×86
Copyright (C) Microsoft Corporation.  All rights reserved.
cl /Fo"c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386/"
/FC
/Ii386
/I.
/I..inc
/Ic:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386
/IC:WinDDK6001.18001incapi
/IC:WinDDK6001.18001incapi
/IC:WinDDK6001.18001incddk
/IC:WinDDK6001.18001incddk
/IC:WinDDK6001.18001inccrt
/D_X86_=1
/Di386=1
/DSTD_CALL
/DCONDITION_HANDLING=1
/DNT_INST=0
/DWIN32=100
/D_NT1X_=100
/DWINNT=1
/D_WIN32_WINNT=0x0501
/DWINVER=0x0501
/D_WIN32_IE=0x0603
/DWIN32_LEAN_AND_MEAN=1
/DDEVL=1
/D__BUILDMACHINE__=WinDDK
/DFPO=0
/DNDEBUG
/D_DLL=1
/DNDEBUG
/DNTDDI_VERSION=0x05010200
/c
/Zc:wchar_t-
/Zl
/Zp8
/Gy
/Gm-
-cbstring
-W3
-WX
/WX
/Gz
/hotpatch
/EHs-c-
/GR-
/GF
/GS
/Zi
/Oxs
/Oy-
/Zi
/Fdc:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386
/DKMDF_MAJOR_VERSION=01
/DKMDF_MINOR_VERSION=007
/FIC:WinDDK6001.18001incapiwarning.h
.acpiec.c .eclowio.c .ecpnp.c .handlers.c .service.c .query.c
acpiec.c
eclowio.c
ecpnp.c
handlers.c
service.c
query.c
Generating Code…
link.exe /out:c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386acpiec.sys /machine:ix86 @c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386lnk.rsp
Microsoft (R) Incremental Linker Version 8.00.50727.278
Copyright (C) Microsoft Corporation.  All rights reserved.
/MERGE:_PAGE=PAGE
/MERGE:_TEXT=.text
/SECTION:INIT,d
/OPT:REF
/OPT:ICF
/IGNORE:4198,4010,4037,4039,4065,4070,4078,4087,4089,4221
/INCREMENTAL:NO
/release
/NODEFAULTLIB
/WX
/debug
/debugtype:cv,fixup,pdata
/version:6.0
/osversion:6.0
/functionpadmin:5
/safeseh
/pdbcompress
/STACK:0x40000,0x1000
/driver
/base:0x10000
/align:0x80 /stub:c:winddk6001.18001libwxpstub512.com
/subsystem:native,5.01
/entry:GsDriverEntry@8
/out:c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386acpiec.sys
c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386acpiec.res
c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386acpiec.obj
c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386eclowio.obj
c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386ecpnp.obj
c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386handlers.obj
c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386service.obj
c:winddk6001.18001srcwdmacpiececobjfre_wxp_x86i386query.obj
c:winddk6001.18001libwxpi386BufferOverflowK.lib
c:winddk6001.18001libwxpi386ntoskrnl.lib
c:winddk6001.18001libwxpi386hal.lib
c:winddk6001.18001libwxpi386wmilib.lib
c:winddk6001.18001libwxpi386sehupd.lib

所有的 ACPI Customer Driver 應該由 GUID_ACPI_INTERFACE_STANDARD 取得 ACPI Driver 本身的界面, 如 ACPIEC driver 的 source 中有一個檔案為 eclowio.c 裡面有一個 AcpiEcGetAcpiInterfaces. 它是在OS的 PNP Manager 去執行 ECAddDevice (in ecpnp.c) 時所被呼叫.

NTSTATUS
AcpiEcGetAcpiInterfaces (
IN PECDATA          EcData
)
/*++

Routine Description:

Call ACPI driver to get the direct-call interfaces.

Arguments:

EcData          – Pointer to the EC driver device extension

Return Value:

Status is returned.

–*/
{
KEVENT              event;
IO_STATUS_BLOCK     ioStatus;
NTSTATUS            status;
PIRP                irp;
PIO_STACK_LOCATION  irpSp;

PAGED_CODE();

//
// Initialize an event to block on
//
KeInitializeEvent( &event, SynchronizationEvent, FALSE );

//
// Build an irp
//
irp = IoBuildSynchronousFsdRequest(
IRP_MJ_PNP,
EcData->LowerDeviceObject,
NULL,
0,
NULL,
&event,
&ioStatus
);

if (!irp) {
return STATUS_INSUFFICIENT_RESOURCES;
}

irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
irp->IoStatus.Information = 0;

//
// Get the the current irp location
//
irpSp = IoGetNextIrpStackLocation( irp );

//
// Use QUERY_INTERFACE to get the address of the direct-call
// ACPI interfaces.
//
irpSp->MajorFunction = IRP_MJ_PNP;
irpSp->MinorFunction = IRP_MN_QUERY_INTERFACE;
irpSp->Parameters.QueryInterface.InterfaceType          = (LPGUID) &GUID_ACPI_INTERFACE_STANDARD;
irpSp->Parameters.QueryInterface.Version                = 1;
irpSp->Parameters.QueryInterface.Size                   = sizeof (AcpiInterfaces);
irpSp->Parameters.QueryInterface.Interface              = (PINTERFACE) &AcpiInterfaces;
irpSp->Parameters.QueryInterface.InterfaceSpecificData  = NULL;

//
// send the request down
//
status = IoCallDriver( EcData->LowerDeviceObject, irp );
if (status == STATUS_PENDING) {

KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
status = ioStatus.Status;

}

//
// Done
//
return status;
}

但是在可以看到當 ECAddDevice 還沒取得 ACPI interface 時, 就在將自己本身掛上 Driver list 後就已經去讀取 EC的 _GPE, 此時就已經可以發IRP 給底層的 ACPI.sys, 去取得ASL中的值!

更有趣的是, 如果用Google 查找 Bob Moore 的話可以找到 Bob Moore robert.moore@intel.com 針對ACPICA/Linux 的commit 所以基本上不管 Windows and Linux 上的 ACPI Driver Stack 應該都是Intel 的一群人寫出來的!

 

關於 ACPI Driver For Windows OS

Posted in ACPI, Win Driver on 2008 年 11 月 27 日 by Kun-Yi

先來聲明下小弟也是只是一個BIOS/EC/WDM的初學者, 現在這裡(Spaces)只記錄學習過程的一些偶得,

有某位仁兄問我 Get ACPI Interface (Get ACPI Interface 我一開始還是反組譯某A公司的Driver Code 得來的, 後來發現 MSFT 的ACPI Interface in Vista 有寫, 舊的DDK也有 wdmec 有相同的 sample code)後, 為啥用 RegisterForDeviceNotifications 會BlueScreen, 說真的小弟 WDM 才剛起步沒幾週, 目前還在找書看, 跟看 WinDDK Sample code的階段, 雖然這幾天有一點Fu 了 (真的花在看東西上差不多一周吧, 大概只到會寫一個 Port/Memory I/O, Functions Driver 是啥, 怎樣 Call Lower Driver to Process Irp 等等), 但是很多問題還是不懂, 尤其是為啥會BlueScreen 那有可能的有問題很多, MSDN 上也是建議依據BugCheck Number 給一些可能的方向而已

不過因為有很好很強大的 Google Code Search 小弟找到了一個 Driver Code (竟然是 Intel’s UrbanMax ACPI to HID Button mapping driver), 有開發 ACPI Driver for Windows OS 需求的可以參考一下

https://code.google.com/p/screenswitcher/source/browse/trunk/goruntu-aktarimi/HidCom64bit/HidMapperCOM/acpihid-x64/src/DispatchPnP.c


今天用 VMWare + WinDBG + WinXP SP2 Free Build 透過置換 ACPI.SYS checked build 抓下來當 XP Boot 時, 會執行的 ACPI Log

Ref. http://msdn.microsoft.com/en-us/library/cc267789.aspx

http://www.osronline.com/article.cfm?id=318

http://www.osronline.com/article.cfm?id=259

然後發現一本中國大陸出版的好書 軟件調試/Software Debugging(台灣習慣用語應該是軟體除錯)  http://advdbg.org/books/swdbg/ , 網站內有一個試閱章節有100頁左右

下面是看來的
關於在Vista中,應該在具有Administrator 等級的Console window 執行下列指令在置換 ACPI.sys:
takeown /f acpi.sys
cacls acpi.sys /G <username>:F

Technorati 的標籤:,,,

ACPI Debugging on Windows Platforms

Posted in ACPI, BIOS, Win Driver on 2008 年 10 月 27 日 by Kun-Yi

MSFT的 TW04015_WINHEC2004.ppt (內容是Implementing, Testing And Debugging ACPI On Windows Platforms)

Update: MSFT上的 link 好像已經失效了, 這擺一份 TW04015_WINHEC2004.ppt 有需要者自取

其中amli 是存在checked build 的acpi.sys 這可以從Microsoft下載, 參考這http://www.microsoft.com/whdc/DevTools/tools/chkblds.mspx,

XP SP2的check build版本

http://download.microsoft.com/download/e/c/6/ec6e00ab-ec05-4673-b8db-0658cf65f043/WindowsXP-KB835935-SP2-DEBUG-ENU.exe

XP SP3的 check build 版本

http://download.microsoft.com/download/4/e/a/4eab3e63-9a62-4473-8af3-87e503603fe2/windowsxp-kb936929-sp3-x86-debug-enu.exe

透過WinDBG 進行 Kernel Debugging時, 可以調用amli 進行ACPI的debug.

安裝了MSFT的 ASL Compiler (個人安裝 3.0.1 version)會有一篇文章講Load Table via Registry(Using the Microsoft ASL Compiler’s ACPI Table Load Utility), 就是透過checked build 的ACPI.SYS 作Developement & Debugging.

Ref.

http://blog.sina.com.cn/s/blog_542734b401000agt.html

http://blog.csdn.net/EFIBIOS/archive/2007/03/12/1526763.aspx

http://blog.chinaunix.net/u/548/showart.php?id=377952

ACPI Debugging, http://msdn.microsoft.com/en-us/library/cc267796.aspx or

http://msdn.microsoft.com/en-us/library/ff537808.aspx

Bookmark :WDK/DDK with Visual Studio

Posted in Win Driver on 2008 年 10 月 16 日 by Kun-Yi

http://www.hollistech.com/Resources/ddkbuild/ddkbuild.htm

ddkbuild 可以將 DDK 的開發 透過Visual Studio 的IDE環境來管理專案

用習慣SlickEdit/Source Insight 的人應該也可以用.(用SlickEdit 確認過了, 可用)

依安裝的DDK/WDF版本要設定一個環境變數, 個人現在測試WDK 6001版,安裝於C:\WinDDK6001.18001下, 所以要有下面的環境變數

set WLHBASE=C:\WinDDK6001.18001

用SlickEdit的話, 可以用Workspace 的Properties 加進去, 不過要重開SlickEdit 2008 才行, 不是像它自己說重開Workspace就行了, 不知道是不是Bug 之一


DDKBUILD VERSION 3.14 FREEWARE FROM HOLLIS TECHNOLOGY SOLUTIONS

Comments? Suggestions? info@hollistech.com

usage: ddkbuild [-debug|-quiet|-verbose] "TARGET" "checked | free" "directory" [flags]

-debug
turns on script echoing for debug purposes

-quiet
supresses almost all output from ddkbuild itself.

-verbose
ddkbuild annotes most of what it does

TARGET
can be any of the following combinations of DDK version and platform OS:

-WLH
indicates development system uses the WHLBASE environment variable to locate WDK versions 6000 or 6001 and build Vista or W2K8 x86 binaries (optional.)

-WLH64
indicates development system uses the WHLBASE environment variable to locate WDK versions 6000 or 6001 and build IA64 W2K8 binaries (optional Untested.)

-WLHA64
indicates development system uses the WHLBASE environment variable to locate WDK versions 6000 or 6001 and build AMD64 (X64) Vista or W2K8 binaries (optional.)

-WLHNET
indicates development system uses the WHLBASE environment variable to locate WDK versions 6000 or 6001 and build W2K3SP1 binaries (optional.)

-WLHNET64
indicates development system uses the WHLBASE environment variable to locate WDK versions 6000 or 6001 and build IA64 W2K3SP1 binaries (optional.)

-WLHNETA64
indicates development system uses the WHLBASE environment variable to locate WDK versions 6000 or 6001 and build AMD64 (X64) W2K3SP1 binaries (optional.)

-WLHXP
indicates development system uses the WHLBASE environment variable to locate WDK versions 6000 or 6001 and build X86 XP binaries (optional.)

-WLHXP64
indicates development system uses the WHLBASE environment variable to locate WDK versions 6000 or 6001 and build IA64 XP binaries (optional.)

-WLHW2K
indicates development system uses the WHLBASE environment variable to locate WDK versions 6000 or 6001 and build X86 W2K binaries (optional.)

-WNET
indicates development system uses WNETBASE environment variable to locate the .Net ddk and builds .net binaries (optional.)

-WNETW2K
indicates development system uses the WNETBASE environment variable to locate the .Net ddk and builds W2K binaries (optional.)

-WNETXP
indicates development system uses WNETBASE environment variable to locate the .Net (W2K3SP1) ddk and builds xp binaries (optional.)

-WNET64
indicates development system uses WNETBASE environment variable to locate the .Net (W2K3SP1) ddk and builds 64bit binaries (optional.)

WNETA64
indicates development system uses WNETBASE environment variable to locate the .Net (W2K3SP1) ddk and builds AMD 64bit binaries (optional.)

-prefast
run prefast rather than a normal build

checked
indicates a checked build.

free
indicates a free build (must choose one or the other of free or checked.)

directory
path to driver source directory. Try . (cwd).

flags
any random flags or arguments you think should be passed to build (note that the visual studio /a for clean build is translated to the equivalent build flag.)
Note also that multiple arguments can be specified by using quotes to contain the set of arguments, as in "-Z foo blortz w2k xp"

example: ddkbuild -WLHXP checked .

NOTE: avoid spaces and other odd characters in pathnames.

Download M$ 的Windows Server 2003 SP1 DDK

Posted in Win Driver on 2007 年 06 月 01 日 by Kun-Yi

Download the Windows Server 2003 SP1 DDK [236 MB ISO file]

from http://www.microsoft.com/whdc/devtools/ddk/default.mspx

M$ 一直搖擺不定很怪得政策 不知道是不是 Vista  出了,所以 Windows Older Driver Architecture 就又開放了

可以直接到上述位置下載 DDK 使用

這是剛剛在找 NDIS Power Management 的方法時的發現。

啊 我的Windows CE Device 在Suspend 時,會因為NDIS Drivers 沒有完成 PownDown,

之後WakeUp 回來裝置就失效了 >_<

USB RNDIS & USB to Lan 都有這個現象 T_T,現在只有Suspend時先Delay 1 second 做 Workaround。

Technorati tags: