2011年03月23日

1>device.obj : error LNK2019: unresolved external symbol _memcmp referenced in function _filterFindFilterModule@8
1>Release\filter.sys : fatal error LNK1120: 1 unresolved externals

再次遇到,又忘了该怎么设置了,多亏小树。。。

用/Oi

 

/Oi(生成内部函数)

 

用有助于应用程序更快运行的内部函数或其他特殊形式的函数替换某些函数调用。

复制

/Oi[-]

备注


使用内部函数的程序比较快,因为它们没有函数调用系统开销。但是,由于创建了附加代码,它们可能比较大。

有关有内部形式的函数的更多信息,请参见 intrinsic

/Oi 仅作为对编译器的请求,用于将某些函数调用替换为内部函数;为产生更好的性能,编译器可能会调用函数(而不会将该函数调用替换为内部函数)。

x86 特定

Note注意

_alloca 和 setjmp 函数始终内联生成;此行为不受 /Oi 影响。

内部浮点函数不对输入值执行任何特殊检查,因此只在有限的输入范围内有效,且与同名库例程具有不同的异常处理和边界条件。使用真正的内部形式意味着失去 IEEE 异常处理以及失去 _matherrerrno 功能;后者意味着失去 ANSI 一致性。然而,内部形式可以显著提高浮点密集型程序的速度,而且对于很多程序来说,一致性问题几乎没有任何价值。

可以使用 /Za、/Ze(禁用语言扩展)重写真正的内部浮点选项的生成。在这种情况下,函数生成为库例程,后者将参数直接传递到浮点芯片,而不是将参数推送到程序堆栈上。

END x86 Specific

还可以使用 intrinsic 创建内部函数,或者使用 function (C/C++) 显式强制函数调用。

在 Visual Studio 开发环境中设置此编译器选项
  1. 打开该项目的“属性页”对话框。有关详细信息,请参见如何:打开项目属性页

  2. 单击“C/C++”文件夹。

  3. 单击“优化”属性页。

  4. 修改“启用内部函数”属性。

以编程方式设置此编译器选项
2011年03月16日

好久没来,donews变word press了,windows live writer还能直接发上来, 呵呵 那太好了

meh。。。 又是一个hello world
这个程序算是我的51 hello world吧,虽然看上去简单,但还是让我郁闷了很久。
里面有些地方值得记一下。
这个程序只是开发板上关于阵列键盘的例子程序,重新写了遍。因为不喜欢汇编,而这个程序原来的c代码实在是没法看。。。
Keil的开发环境也确实太难用,能用c写代码已经很感激了。。。
写51的程序还不熟练,貌似片上的内存只有128 byte?也许函数和局部变量该少用写,已经尽量简单了,比如得到键盘输入的函数里面直接就把结果写到数码
管上了。
0001
0002 /********************************************************************************
0003 *  描述:                                                                       *
0004 *                   矩阵键盘数码管显示键值                                     *
0005 *   排线连接方法:JP8(P1) 与JP4(矩阵键盘接口)连接  P0与JP3(静态数码管)连接 *
0006 *         矩阵键盘定义:                                                       *
0007 *         P1.4-P1.7为列线,P1.1-P1.3为行线                                      *
0008 *         喇叭接P1.5口  矩阵键盘P1口,                                         *
0009 *  注意:请将JP165短路冒断开                                                   *
0010 ********************************************************************************/
0011
0012
0013 #include <reg51.h>
0014 #include <intrins.h>
0015
0016 //-----------------------------------------------------------------------------//
0017 // 此表为 LED 的字模                 0      1        2     3       4     5        6     7        8     9      a          b       c    d      e         f
0018 unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};
0019 //-----------------------------------------------------------------------------//
0020 /*************************************************************/
0021 /*                                                           */
0022 /* 延时子程序                                                */
0023 /*                                                           */
0024 /*************************************************************/
0025
0026 void  delay(unsigned int x)
0027 {
0028     unsigned char j;
0029
0030     while((x--)!=0)
0031     {
0032         for(j=0;j<125;j++)
0033          {;}
0034     }
0035 }
0036 //-----------------------------------------------------------------------------//
0037 unsigned char
0038 GetNumber ()
0039 {
0040     char i = 0;
0041     char j = 0;
0042
0043     unsigned char temp = 0;
0044
0045
0046     P1 = 0x0F;
0047     temp = P1;
0048
0049     if (0xD == temp) // 0000 1101
0050     {
0051         i = 0;
0052     }
0053     else if (0xB == temp) // 0000 1011
0054     {
0055         i = 1;
0056     }
0057     else if (0x7 == temp)    // 0000 0111
0058     {
0059         i = 2;
0060     }
0061     else
0062     {
0063         // error
0064         return 0xE;
0065     }
0066
0067
0068     P1 = 0xF0;
0069     temp = P1;
0070
0071     if (0x70 == temp) // 0111 0000
0072     {
0073         j = 3;
0074     }
0075     else if (0xB0 == temp) // 1011 0000
0076     {
0077         j = 2;
0078     }
0079     else if (0xD0 == temp) // 1101 0000
0080     {
0081         j = 1;
0082     }
0083     else if (0xE0 == temp) // 1110 0000
0084     {
0085         j = 0;
0086     }
0087     else
0088     {
0089         // error
0090         return 0xE;
0091     }
0092
0093     return i * 4 + j;
0094 }
0095 //-----------------------------------------------------------------------------//
0096 void
0097 ScanKey ()
0098 {
0099     unsigned char ucNumber = 0;
0100
0101     P1 = 0xF0;
0102
0103     if (0xF0 != P1)
0104     {
0105         // key down, get scan code
0106         ucNumber = GetNumber();
0107
0108         // display
0109         P0 = LED7Code[ucNumber];
0110     }
0111
0112     delay(50);        //去抖动
0113 }
0114 //-----------------------------------------------------------------------------//
0115 void
0116 main()
0117 {
0118     P0 = 0xFF;
0119     P1 = 0xFF;
0120
0121
0122     P0 = LED7Code[0];
0123
0124     while(1)
0125     {
0126         ScanKey();
0127     }
0128 }
 
写程序的时候需要看电路图
矩阵键盘电路图
1.开始以为P1到P7都是能得到输入的,这样行和列一起就得到了。后来发现这样不行。。。
阵列键盘本身不带电源,不能输入信号。从图上看P1.1-P1.3表示行P1.4-P1.7表示列,而行和列通过按键连在一起。当一个按键按下去的时候,就会联通
其中的2个针脚。
2.按键的去抖动
不用加在P1 = 0xF0; 后,而是在处理完一次按键后delay一会就行。如果很快的再次检测P1,会出现重复处理按键的情况。
3.开始调程序的时候遇到了Keil环境里P0的值和Pin上的值不一样的情况
P0
似乎就是P0 Pins的值只能由1变0,却不能由0变1,而P1,P2,P3都没有这个问题。
8051 Port Bit Latches and io buffers
80C51_FAM_HARDWARE_1里面的图,结合着《The 8051 Microcontroller》里面的解释,对于P0来说:When userd as an output,
the pin latches that are programmed to a 0 will turn on the lower FET, grounding the pin.
但并不影响输出,数码管上确实现实出了正确的数据,开来输出用的是Latch上的值。
4.
    Ports 1, 2, and 3 have internal pullups, and Port 0 has open drain
outputs. Each I/O line can be independently used as an input or an
output. (Port 0 and 2 may not be used as general purpose I/O when
being used as the ADDR/DATA BUS for external memory during
normal operation.) To be used as an input, the port bit latch must
contain a 1, which turns off the output driver FET. Then, for Ports 1,
2, and 3, the pin is pulled high by a weak internal pullup, and can be
pulled low by an external source.
    Port 0 differs in that its internal pullups are not active during normal
port operation. The pullup FET in the P0 output driver (see Figure 4)
is used only when the port is emitting 1s during external memory
accesses. Otherwise the pullup FET is off. Consequently P0 lines
that are being used as output port lines are open drain. Writing a 1
to the bit latch leaves both output FETs off, so the pin floats. In that
condition it can be used as a high-impedance input.
    Because Ports 1, 2, and 3 have fixed internal pullups, they are
sometimes called “quasi- bidirectional” ports. When configured as
inputs they pull high and will source current (IIL, in the data sheets)
when externally pulled low. Port 0, on the other hand, is considered
“true” bidirectional, because when configured as an input it floats.
    All the port latches in the 80C51 have 1s written to them by the reset
function. If a 0 is subsequently written to a port latch, it can be
reconfigured as an input by writing a 1 to it.
也就是说 P0 P1 P2 P3要用输入数据前先要置1。这导致我开始获得P1的输入之前先P1 = 0xFF了,就没有好好看电路图。
 
2009年03月03日

肯定不是2^64那么多 从hardware pte里看PageFramNumber,是28bit

再看32bit的windows 普通的是20bit, pae的是26

2^28就是windows能表示的物理内存了吧, 以前还真没注意过这个。。

说错了请告诉 : p

2009年01月28日

http://uayuty.cn

http://shop37037561.taobao.com/

哈哈 还没想明白卖啥, 先卖点毛绒玩具, 进货犯了个错误, 买的都是我喜欢的…. 其他人不买账啊
就没人喜欢机器猫了吗.. 反到是uay挑的流氓兔子卖的很快, 2天就卖了19个
我品位确实有问题….

2008年12月03日

IsBadReadPtr Function

Verifies that the calling process has read access to the specified range of memory.

Important This function is obsolete and should not be used. Despite its name, it does not guarantee that the pointer is valid or that the memory pointed to is safe to use. For more information, see Remarks on this page.

Syntax

BOOL WINAPI IsBadReadPtr(
__in const VOID *lp,
__in UINT_PTR ucb
);
Parameters
lp [in]
A pointer to the first byte of the memory block.

ucb [in]
The size of the memory block, in bytes. If this parameter is zero, the return value is zero.

Return Value
If the calling process has read access to all bytes in the specified memory range, the return value is zero.

If the calling process does not have read access to all bytes in the specified memory range, the return value is nonzero.

If the application is compiled as a debugging version, and the process does not have read access to all bytes in the specified memory range, the function causes an assertion and breaks into the debugger. Leaving the debugger, the function continues as usual, and returns a nonzero value. This behavior is by design, as a debugging aid.

Remarks
This function is typically used when working with pointers returned from third-party libraries, where you cannot determine the memory management behavior in the third-party DLL.

Threads in a process are expected to cooperate in such a way that one will not free memory that the other needs. Use of this function does not negate the need to do this. If this is not done, the application may fail in an unpredictable manner.

Dereferencing potentially invalid pointers can disable stack expansion in other threads. A thread exhausting its stack, when stack expansion has been disabled, results in the immediate termination of the parent process, with no pop-up error window or diagnostic information.

If the calling process has read access to some, but not all, of the bytes in the specified memory range, the return value is nonzero.

In a preemptive multitasking environment, it is possible for some other thread to change the process’s access to the memory being tested. Even when the function indicates that the process has read access to the specified memory, you should use structured exception handling when attempting to access the memory. Use of structured exception handling enables the system to notify the process if an access violation exception occurs, giving the process an opportunity to handle the exception.

Requirements
Minimum supported client Windows 2000 Professional
Minimum supported server Windows 2000 Server
Header Winbase.h (include Windows.h)
Library Kernel32.lib
DLL Kernel32.dll

See Also
IsBadCodePtr
IsBadStringPtr
IsBadWritePtr

Send comments about this topic to Microsoft

Build date: 11/6/2008

Tags : Add a tag Add Cancel Flag as ContentBug

Community Content
Add new content Annotations

Raymond Chen (The Old New Thing) says: never ever use this function Peter Smith in Redmond | Edit | Show History
Please Wait
Via Raymond Chen’s “The Old New Thing” blog,

http://blogs.msdn.com/oldnewthing/archive/2006/09/27/773741.aspx

IsBadXxxPtr should really be called CrashProgramRandomly
Often I’ll see code that tries to “protect” against invalid pointer parameters. This is usually done by calling a function like IsBadWritePtr. But this is a bad idea. IsBadWritePtr should really be called CrashProgramRandomly.
The documentation for the IsBadXxxPtr functions presents the technical reasons why, but I’m going to dig a little deeper. For one thing, if the “bad pointer” points into a guard page, then probing the memory will raise a guard page exception. The IsBadXxxPtr function will catch the exception and return “not a valid pointer”. But guard page exceptions are raised only once. You just blew your one chance. When the code that is managing the guard page accesses the memory for what it thinks is the first time (but is really the second), it won’t get the guard page exception but will instead get a normal access violation.
Alternatively, it’s possible that your function was called by some code that intentionally passed a pointer to a guard page (or a PAGE_NOACCESS page) and was expecting to receive that guard page exception or access violation exception so that it could dynamically generate the data that should go onto that page. (Simulation of large address spaces via pointer-swizzling is one scenario where this can happen.) Swallowing the exception in IsBadXxxPtr means that the caller’s exception handler doesn’t get a chance to run, which means that your code rejected a pointer that would actually have been okay, if only you had let the exception handler do its thing.
“Yeah, but my code doesn’t use guard pages or play games with PAGE_NOACCESS pages, so I don’t care.” Well, for one thing, just because your code doesn’t use these features pages doesn’t mean that no other code in your process uses them. One of the DLLs that you link to might use guard pages, and your use of IsBadXxxPtr to test a pointer into a guard page will break that other DLL.
And second, your program does use guard pages; you just don’t realize it. The dynamic growth of the stack is performed via guard pages: Just past the last valid page on the stack is a guard page. When the stack grows into the guard page, a guard page exception is raised, which the default exception handler handles by committing a new stack page and setting the next page to be a guard page.
(I suspect this design was chosen in order to avoid having to commit the entire memory necessary for all thread stacks. Since the default thread stack size is a megabyte, this would have meant that a program with ten threads would commit ten megabytes of memory, even though each thread probably uses only 24KB of that commitment. When you have a small pagefile or are running without a pagefile entirely, you don’t want to waste 97% of your commit limit on unused stack memory.)
“But what should I do, then, if somebody passes me a bad pointer?”
You should crash.
No, really.
In the Win32 programming model, exceptions are truly exceptional. As a general rule, you shouldn’t try to catch them. And even if you decide you want to catch them, you need to be very careful that you catch exactly what you want and no more.
Trying to intercept the invalid pointer and returning an error code creates nondeterministic behavior. Where do invalid pointers come from? Typically they are caused by programming errors. Using memory after freeing it, using uninitialized memory, that sort of thing. Consequently, an invalid pointer might actually point to valid memory, if for example the heap page that used to contain the memory has not been decomitted, or if the uninitialized memory contains a value that when reinterpreted as a pointer just happens to be a pointer to memory that is valid right now. On the other hand, it might point to truly invalid memory. If you use IsBadWritePtr to “validate” your pointers before writing to them, then in the case where it happens to point to memory that is valid, you end up corrupting memory (since the pointer is “valid” and you therefore decide to write to it). And in the case where it happens to point to an invalid address, you return an error code. In both cases, the program keeps on running, and then that memory corruption manifests itself as an “impossible” crash two hours later.
In other words IsBadWritePtr is really CorruptMemoryIfPossible. It tries to corrupt memory, but if doing so raises an exception, it merely fails the operation.
Many teams at Microsoft have rediscovered that IsBadXxxPtr causes bugs rather than fixes them. It’s not fun getting a bucketful of crash dumps and finding that they are all of the “impossible” sort. You hunt through your code in search of this impossible bug. Maybe you find somebody who was using IsBadXxxPtr or equivalently an exception handler that swallows access violation exceptions and converts them to error codes. You remove the IsBadXxxPtr in order to let the exception escape unhandled and crash the program. Then you run the scenario again. And wow, look, the program crashes in that function, and when you debug it, you find the code that was, say, using a pointer after freeing it. That bug has been there for years, and it was manifesting itself as an “impossible” bug because the function was trying to be helpful by “validating” its pointers, when in fact what it was doing was taking a straightforward problem and turning it into an “impossible” bug.
There is a subtlety to this advice that you should just crash when given invalid input, which I’ll take up next time.

Tags : Add a tag Add Cancel Flag as ContentBug
| Edit

Tags : Add a tag Add Cancel Flag as ContentBug

Manage Your Profile | Legal | Contact Us | MSDN Flash Newsletter
© 2008 Microsoft Corporation. All rights reserved. Terms of Use | Trademarks | Privacy Statement

2008年12月01日

kd> dd nt!NtCancelDeviceWakeupRequest
805bde0e 000002b8 0004c2c0 cccccccc 74a0cccc
805bde1e 2480559a 1ad8f603 c3c0fec0 cccccccc
805bde2e 1c6acccc 4daa1068 a2a4e880 a164fff7
805bde3e 00000124 0140808a db330000 3874c33a
805bde4e 8bfc5d89 b4a10c7d 3b80558b 890272f8
805bde5e 89078b18 fc4d8307 8b20ebff 008bec45
805bde6e 4589008b 40c033dc e8658bc3 fffc4d83
805bde7e e9dc458b 00000082 640c7d8b 000124a1
kd> u 805bde0e
nt!NtModifyBootEntry:
805bde0e b8020000c0 mov eax,0C0000002h
805bde13 c20400 ret 4
805bde16 cc int 3
805bde17 cc int 3
805bde18 cc int 3
805bde19 cc int 3
805bde1a cc int 3
805bde1b cc int 3

2008年10月28日

三种链表是InLoadOrderModuleList , InMemoryOrderModuleList , InInitializationOrderModuleList

lkd> !peb
PEB at 7ffd5000
    InheritedAddressSpace:    No
    ReadImageFileExecOptions: No
    BeingDebugged:            No
    ImageBaseAddress:         01000000
    Ldr                       00191e90
    Ldr.Initialized:          Yes
    Ldr.InInitializationOrderModuleList: 00191f28 . 00195a38
    Ldr.InLoadOrderModuleList:           00191ec0 . 00195a28
    Ldr.InMemoryOrderModuleList:         00191ec8 . 00195a30

lkd> dt nt!_PEB_LDR_DATA 00191e90
   +0×000 Length           : 0×28
   +0×004 Initialized      : 0×1 ”
   +0×008 SsHandle         : (null)
   +0×00c InLoadOrderModuleList : _LIST_ENTRY [ 0x191ec0 - 0x195a28 ]
   +0×014 InMemoryOrderModuleList : _LIST_ENTRY [ 0x191ec8 - 0x195a30 ]
   +0×01c InInitializationOrderModuleList : _LIST_ENTRY [ 0x191f28 - 0x195a38 ]
   +0×024 EntryInProgress  : (null)

lkd> dt nt!_LDR_DATA_TABLE_ENTRY 0×191ec0
   +0×000 InLoadOrderLinks : _LIST_ENTRY [ 0x191f18 - 0x191e9c ]
   +0×008 InMemoryOrderLinks : _LIST_ENTRY [ 0x191f20 - 0x191ea4 ]
   +0×010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0×018 DllBase          : 0×01000000
   +0×01c EntryPoint       : 0×01056217
   +0×020 SizeOfImage      : 0×93000
   +0×024 FullDllName      : _UNICODE_STRING "C:\Program Files\Debugging Tools for Windows (x86)\windbg.exe"
   +0×02c BaseDllName      : _UNICODE_STRING "windbg.exe"
   +0×034 Flags            : 0×5000
   +0×038 LoadCount        : 0xffff
   +0×03a TlsIndex         : 0
   +0×03c HashLinks        : _LIST_ENTRY [ 0x19362c - 0x7c99b310 ]
   +0×03c SectionPointer   : 0×0019362c
   +0×040 CheckSum         : 0×7c99b310
   +0×044 TimeDateStamp    : 0×47e30f97
   +0×044 LoadedImports    : 0×47e30f97
   +0×048 EntryPointActivationContext : (null)
   +0×04c PatchInformation : (null)

lkd> dt nt!_LDR_DATA_TABLE_ENTRY 0×191ec8-0×8
   +0×000 InLoadOrderLinks : _LIST_ENTRY [ 0x191f18 - 0x191e9c ]
   +0×008 InMemoryOrderLinks : _LIST_ENTRY [ 0x191f20 - 0x191ea4 ]
   +0×010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0×018 DllBase          : 0×01000000
   +0×01c EntryPoint       : 0×01056217
   +0×020 SizeOfImage      : 0×93000
   +0×024 FullDllName      : _UNICODE_STRING "C:\Program Files\Debugging Tools for Windows (x86)\windbg.exe"
   +0×02c BaseDllName      : _UNICODE_STRING "windbg.exe"
   +0×034 Flags            : 0×5000
   +0×038 LoadCount        : 0xffff
   +0×03a TlsIndex         : 0
   +0×03c HashLinks        : _LIST_ENTRY [ 0x19362c - 0x7c99b310 ]
   +0×03c SectionPointer   : 0×0019362c
   +0×040 CheckSum         : 0×7c99b310
   +0×044 TimeDateStamp    : 0×47e30f97
   +0×044 LoadedImports    : 0×47e30f97
   +0×048 EntryPointActivationContext : (null)
   +0×04c PatchInformation : (null)

lkd> dt nt!_LDR_DATA_TABLE_ENTRY 0×191f28-0×10
   +0×000 InLoadOrderLinks : _LIST_ENTRY [ 0x191fc0 - 0x191ec0 ]
   +0×008 InMemoryOrderLinks : _LIST_ENTRY [ 0x191fc8 - 0x191ec8 ]
   +0×010 InInitializationOrderLinks : _LIST_ENTRY [ 0x191fd0 - 0x191eac ]
   +0×018 DllBase          : 0×7c920000
   +0×01c EntryPoint       : 0×7c932c28
   +0×020 SizeOfImage      : 0×93000
   +0×024 FullDllName      : _UNICODE_STRING "C:\WINDOWS\system32\ntdll.dll"
   +0×02c BaseDllName      : _UNICODE_STRING "ntdll.dll"
   +0×034 Flags            : 0×80084004
   +0×038 LoadCount        : 0xffff
   +0×03a TlsIndex         : 0
   +0×03c HashLinks        : _LIST_ENTRY [ 0x1936d4 - 0x7c99b2c8 ]
   +0×03c SectionPointer   : 0×001936d4
   +0×040 CheckSum         : 0×7c99b2c8
   +0×044 TimeDateStamp    : 0×4802bdc5
   +0×044 LoadedImports    : 0×4802bdc5
   +0×048 EntryPointActivationContext : (null)
   +0×04c PatchInformation : (null)

可以看出来前2个链表InLoadOrderModuleList , InMemoryOrderModuleList 这2个表是一样的, 以进程exe为链首. InInitializationOrderModuleList 以ntdll.dll为链首.

进程exe不加入到InInitializationOrderModuleList 链表, 其他顺序3个表一致, 这也是为什么进程exe在InLoadOrderModuleList , InMemoryOrderModuleList里+0×010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]为空的原因

2008年07月22日
#ifndef _DISK_HIVE_SUBS_H_
#define _DISK_HIVE_SUBS_H_
//-----------------------------------------------------------------------------//
#define HIVE_SYSTEM	0
#define HIVE_SOFTWARE	1
//-----------------------------------------------------------------------------//
LONG
NIAPHiveOpenHive(
	IN  ULONG ulHive,
	OUT PHANDLE phFileHandle,
	OUT PHANDLE phFileMappingHandle,
	OUT PHANDLE phHiveHandle // hive file map base
	);

LONG
NIAPHiveCloseHive(
	IN HANDLE hFileHandle,
	IN HANDLE hFileMappingHandle,
	IN HANDLE hHiveHandle // hive file map base
	);

LONG
NIAPHiveOpenKey(
	IN  HANDLE  hHiveHandle,
	IN  PWCHAR  pwstrKeyPath,
	OUT PHANDLE phKeyHandle
	);

LONG
NIAPHiveQueryInfoKey(
	IN  HANDLE  hHiveHandle,
	IN  HANDLE  hKey,
	OUT PULONG  pulSubKeys OPTIONAL,
	OUT PULONG  pulValues OPTIONAL,
	OUT PULONG  pulMaxNameLen OPTIONAL,
	OUT PULONG  pulMaxClassLen OPTIONAL,
	OUT PULONG  pulMaxValueNameLen OPTIONAL,
	OUT PULONG  pulMaxValueDataLen OPTIONAL
	);

LONG
NIAPHiveEnumKey(
	IN  HANDLE hHiveHandle,
	IN  HANDLE hKey,
	IN  ULONG  ulIndex,
	OUT PWCHAR pwstrName,
	IN  ULONG  ulNameSize
	);

LONG
NIAPHiveEnumValue(
	IN  HANDLE hHiveHandle,
	IN  HANDLE hKey,
	IN  ULONG ulIndex,
	OUT PWCHAR pwstrValueName,
	IN  PULONG pulValueNameSize,
	OUT PULONG pulType OPTIONAL,
	OUT PVOID pData OPTIONAL,
	IN OUT PULONG pulDataLen OPTIONAL
	);

LONG
NIAPHiveCloseKey(
	IN HANDLE hHiveHandle,
	IN HANDLE hKey
	);
//-----------------------------------------------------------------------------//
#endif

 

Example Code:

#include <Windows.h>
#include <stdio.h>
#include "diskhivesubs.h"
//-----------------------------------------------------------------------------//
int wmain(int argc, PWCHAR argv[])
{
	LONG lResult = -1;

	HANDLE hFileHandle = INVALID_HANDLE_VALUE;
	HANDLE hFileMappingHandle = INVALID_HANDLE_VALUE;
	HANDLE hHiveHandle = NULL;
	HANDLE hKeyHandle = INVALID_HANDLE_VALUE;

	ULONG  ulSubKeys = 0;
	ULONG  ulValues = 0;
	ULONG  ulMaxNameLen = 0;
	ULONG  ulMaxClassLen = 0;
	ULONG  ulMaxValueNameLen = 0;
	ULONG  ulMaxValueDataLen = 0;

	PWCHAR pwstrSubKeyNameBuffer = NULL;
	PWCHAR pwstrValueNameBuffer = NULL;
	ULONG ulValueNameSize = 0;

	HANDLE hStdOut = INVALID_HANDLE_VALUE;

	ULONG ulBytesWritten = 0;

	PVOID pValueData = NULL;
	ULONG ulValueDataLen = 0;

	ULONG i = 0;

	hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
	if (INVALID_HANDLE_VALUE == hStdOut)
	{
		goto Exit0;
	}

	lResult = NIAPHiveOpenHive(HIVE_SYSTEM, &hFileHandle, &hFileMappingHandle, &hHiveHandle);
	if (ERROR_SUCCESS != lResult)
	{
		goto Exit0;
	}

	lResult = NIAPHiveOpenKey(hHiveHandle, argv[1], &hKeyHandle);
	if (ERROR_SUCCESS != lResult)
	{
		printf("NIAPHiveOpenKey fail!\n");
		goto Exit0;
	}
	else
	{
		printf("NIAPHiveOpenKey success, ulKeyHandle 0x%x\n", (ULONG)hKeyHandle);
	}

	lResult = NIAPHiveQueryInfoKey(hHiveHandle, hKeyHandle,
		&ulSubKeys,
		&ulValues,
		&ulMaxNameLen,
		&ulMaxClassLen,
		&ulMaxValueNameLen,
		&ulMaxValueDataLen
		);

	if (ERROR_SUCCESS != lResult)
	{
		printf("NIAPHiveQueryInfoKey fail!\n");
	}
	else
	{
		printf("NIAPHiveQueryInfoKey success\n");
		printf("ulSubKeys: %d\n", ulSubKeys);
		printf("ulValues: %d\n", ulValues);
		printf("ulMaxNameLen: %d\n", ulMaxNameLen);
		printf("ulMaxClassLen: %d\n", ulMaxClassLen);
		printf("ulMaxValueNameLen: %d\n", ulMaxValueNameLen);
		printf("ulMaxValueDataLen: %d\n", ulMaxValueDataLen);
	}

	pwstrSubKeyNameBuffer = malloc(ulMaxNameLen + sizeof(UNICODE_NULL));
	if (NULL == pwstrSubKeyNameBuffer)
	{
		lResult = -1;
		goto Exit0;
	}
	memset(pwstrSubKeyNameBuffer, 0, ulMaxNameLen + sizeof(UNICODE_NULL));

	pwstrValueNameBuffer = malloc(ulMaxValueNameLen + sizeof(UNICODE_NULL));
	if (NULL == pwstrValueNameBuffer)
	{
		lResult = -1;
		goto Exit0;
	}
	memset(pwstrValueNameBuffer, 0, ulMaxValueNameLen + sizeof(UNICODE_NULL));

	for (i = 0; i < ulSubKeys; i++)
	{
		memset(pwstrSubKeyNameBuffer, 0, ulMaxNameLen + sizeof(UNICODE_NULL));
		lResult = NIAPHiveEnumKey(hHiveHandle, hKeyHandle, i, pwstrSubKeyNameBuffer, (ulMaxNameLen + sizeof(UNICODE_NULL)) / sizeof(WCHAR));
		if (ERROR_SUCCESS != lResult)
		{
			printf("NIAPHiveEnumKey fail!\n");
			goto Exit0;
		}
		WriteConsole( hStdOut, pwstrSubKeyNameBuffer, (ulMaxNameLen + sizeof(UNICODE_NULL)) / sizeof(WCHAR), &ulBytesWritten, NULL);
		WriteConsole( hStdOut, L"\n", 1, &ulBytesWritten, NULL);
	}

	printf("Value:\n");

	ulValueDataLen = ulMaxValueDataLen;

	pValueData = malloc(ulValueDataLen);
	if (NULL == pValueData)
	{
		lResult = -1;
		goto Exit0;
	}

	for (i = 0; i < ulValues; i++)
	{
		ULONG ulType = 0;

		ulValueDataLen = ulMaxValueDataLen;
		memset(pValueData, 0, ulValueDataLen);

		ulValueNameSize = (ulMaxValueNameLen + sizeof(UNICODE_NULL)) / sizeof(WCHAR);
		memset(pwstrValueNameBuffer, 0, ulMaxValueNameLen + sizeof(UNICODE_NULL));
		lResult = NIAPHiveEnumValue(hHiveHandle, hKeyHandle, i, pwstrValueNameBuffer, &ulValueNameSize,
			                        &ulType, pValueData, &ulValueDataLen);
		if (ERROR_SUCCESS != lResult)
		{
			printf("NIAPHiveEnumValue fail, 0x%x\n", lResult);
			goto Exit0;
		}
		WriteConsole( hStdOut, pwstrValueNameBuffer, ulValueNameSize, &ulBytesWritten, NULL);

		switch(ulType)
		{
		case REG_DWORD:
			{
				printf(" Type: REG_DWORD");
				printf(" Value: %d", *(PULONG)pValueData);
			}
			break;
		case REG_SZ:
			{
				printf(" Type: REG_SZ");
				printf(" Value: ");
				WriteConsole( hStdOut, (PWCHAR)pValueData, ulValueDataLen / sizeof(WCHAR), &ulBytesWritten, NULL);
			}
			break;
		case REG_EXPAND_SZ:
			{
				printf(" Type: REG_EXPAND_SZ");
				printf(" Value: ");
				WriteConsole( hStdOut, (PWCHAR)pValueData, ulValueDataLen / sizeof(WCHAR), &ulBytesWritten, NULL);
			}
			break;
		default:
			break;
		}
		WriteConsole( hStdOut, L"\n", 1, &ulBytesWritten, NULL);
	}

	lResult = ERROR_SUCCESS;
Exit0:
	if (NULL != pValueData)
	{
		free(pValueData);
	}
	if (NULL != pwstrSubKeyNameBuffer)
	{
		free(pwstrSubKeyNameBuffer);
	}
	if (NULL != pwstrValueNameBuffer)
	{
		free(pwstrValueNameBuffer);
	}
	if (INVALID_HANDLE_VALUE != hKeyHandle)
	{
		NIAPHiveCloseKey(hHiveHandle, hKeyHandle);
	}
	if ((NULL != hHiveHandle) && (INVALID_HANDLE_VALUE != hFileMappingHandle) && (INVALID_HANDLE_VALUE != hFileHandle))
	{
		NIAPHiveCloseHive(hFileHandle, hFileMappingHandle, hHiveHandle);
	}
	return lResult;
}
//-----------------------------------------------------------------------------//
 
2008年05月11日

驱动拦截键盘输入 保护密码不被截获

拦截dll加载,对应用程序做保护

主要用于网游和im的密码输入保护

有意请联系 niapsoft@hotmail.com