阅读:1372回复:6
Question about Device Timer
我在一个Timer例程里,其实什么都没做,就是查询了一下注册表,
并且将查询到的值加一,不是为什么执行了一段时间后,如从1加到30后,出现兰屏。 好像是 ATTEMPT_SWITCH_FROM_DPC,(不知道有没有写错),请大家给我点意见。 |
|
最新喜欢:znsoft
|
沙发#
发布于:2002-05-09 13:11
是不是IRQL不正确?一般来说,查询注册表的函数需要运行在PASSIVE_LEVEL上。把你的代码贴出来看看。
|
|
板凳#
发布于:2002-05-09 15:43
InitializeObjectAttributes(
&objectAttributes, &uniRegPath, OBJ_CASE_INSENSITIVE, NULL, NULL ); // Open the regstry key status = ZwOpenKey( &handle, KEY_WRITE, &objectAttributes ); // // Query the curren value // keyinfo = ExAllocatePool(NonPagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION)+sizeof(ULONG)-1 ); RtlZeroMemory( keyinfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION)+sizeof(ULONG)-1 ); keyinfo->Type = REG_DWORD; keyinfo->DataLength = sizeof(ULONG); status = ZwQueryValueKey( handle, &uniRegValue, KeyValuePartialInformation, keyinfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION)+sizeof(ULONG)-1, &ulReturned ); ulValue = *(ULONG*)keyinfo->Data; ulValue++; // set the current value status = ZwSetValueKey( handle, &uniRegValue, 0, REG_DWORD, &ulValue, sizeof(ULONG) ); ZwClose( handle ); |
|
|
地板#
发布于:2002-05-09 21:01
调用ZwOpenKey例程之后有没有检查返回值或者返回句柄。因为句柄是与进程相关的,也就是说即使你打开的是同一个对象,但是在不同的进程中返回的句柄可能是不一样的。在一个进程中打开的句柄在另外一个进程中可能就是非法的。
有没有可能有这样一种情况:你的Timer例程正好运行在系统Idle线程环境下。我不能肯定在系统Idle线程环境下可不可以通过句柄来访问一个对象,不过你可以用SoftICE跟踪一下,看看你的Timer例程到底运行在哪个线程环境下(thread命令可以查看当前线程)。 我觉得你最好不要在不确定的线程环境下使用句柄,因为我们不知道系统调度器(运行在IRQL DISPATCH_LEVEL上)会做一些什么让我们吃惊的事情。另外,DDK号称ZwOpenKey等例程应该运行在IRQL PASSIVE_LEVEL上,我们最好遵守这个规则,虽然这个问题未必就是因为IRQL的问题引起的。 |
|
地下室#
发布于:2002-05-10 17:36
应该就是ZwOpenKey...那几个函数的调用级别的问题吧。
死的时候在system线程中。 你的第一段话,没明白。我没检查,是因为我在贴出来时删了。我在一次Timer例程中可能出现你说的情况吗,不会吧。 那我现在如果要跟注册表打叫道,怎么办,开一个系统线程? |
|
|
5楼#
发布于:2002-05-10 17:58
每个进程都会维护一个句柄表(Handle Table),但是每个进程所维护的句柄表都不同。比如说:进程A打开了一个句柄值0x40,它代表一个File Object;进程B也打开了同一个File Object,它也会得到一个句柄值,但是有可能是0x80,而不一定是0x40,但是它们都代表的是同一个对象。我想如果你想访问注册表的话,最好创建一个系统线程。
|
|
6楼#
发布于:2002-05-10 18:21
你说的这个,我明白,但是这个在这里没什么关系的吧
|
|
|