CloseHandle的安全性问题 ( 积分: 30 )

  • 主题发起人 主题发起人 sy0116
  • 开始时间 开始时间
S

sy0116

Unregistered / Unconfirmed
GUEST, unregistred user!
我用API做了一个串口通讯程序,在程序退出时用CloseHandle(hCOMPort)来关闭串口,但是我发现一个很严重的问题,因为这个串口设备是通过USB来模拟出来的,而USB是可以热插拔的,所以如果没有退出程序就拔掉设备再退出就会引起蓝屏,而且,如果没有退出程序就用“休眠”来关机,则下次启动系统时就无法访问串口设备,此时退出程序也会蓝屏,请问有什么办法能解决这个问题?可别告诉我不用CloseHandle啊
 
不用好了,程序退出的时候是会自动释放的。<br><br>既然模拟出COM口,热拔插的特性当然也就消失了,硬要拔的话,就是用户问题。
 
那休眠的问题如何解决呢?
 
不Closehandle就没事了吧?
 
有没有什么直接或间接的办法能够知道一个Handle是否有效呢?
 
我的想法,<br>类似于消息截获,<br>if&nbsp;(拔usb)&nbsp;or&nbsp;(休眠)&nbsp;then<br>&nbsp;&nbsp;closeHandle;
 
不是很好的方法,但可以试试<br><br>const<br>&nbsp;&nbsp;NtDllName&nbsp;=&nbsp;'ntdll.dll';<br><br><br>&nbsp;&nbsp;TNtUnicodeString&nbsp;=&nbsp;packed&nbsp;record<br>&nbsp;&nbsp;&nbsp;&nbsp;Length:&nbsp;Word;<br>&nbsp;&nbsp;&nbsp;&nbsp;MaximumLength:&nbsp;Word;<br>&nbsp;&nbsp;&nbsp;&nbsp;Buffer:&nbsp;array[0..MAX_PATH]&nbsp;of&nbsp;WideChar;//;PWideChar;<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;PNtUnicodeString&nbsp;=&nbsp;^TNtUnicodeString;<br>&nbsp;&nbsp;UNICODE_STRING&nbsp;=&nbsp;TNtUnicodeString;<br>&nbsp;&nbsp;PUNICODE_STRING&nbsp;=&nbsp;^UNICODE_STRING;<br><br>&nbsp;&nbsp;OBJECT_NAME_INFORMATION&nbsp;=&nbsp;UNICODE_STRING;<br>&nbsp;&nbsp;POBJECT_NAME_INFORMATION&nbsp;=&nbsp;^OBJECT_NAME_INFORMATION;<br><br>type<br>&nbsp;&nbsp;TNtQueryObject&nbsp;=&nbsp;function(&nbsp;ObjectHandle:&nbsp;THANDLE;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectInformationClass:&nbsp;DWORD;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ObjectInformation:&nbsp;Pointer;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ALength:&nbsp;DWORD;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ResultLength:&nbsp;PDWORD):&nbsp;Integer;stdcall;<br><br>function&nbsp;GetObjectName(hObject:&nbsp;THANDLE):&nbsp;string;<br>var<br>&nbsp;&nbsp;dwSize:&nbsp;DWORD;<br>&nbsp;&nbsp;pObjectInfo:&nbsp;POBJECT_NAME_INFORMATION;<br>&nbsp;&nbsp;pNTQO:&nbsp;TNtQueryObject;<br>&nbsp;&nbsp;ret:&nbsp;Integer;<br><br>begin<br>&nbsp;&nbsp;Result&nbsp;:=&nbsp;&nbsp;'';<br>&nbsp;&nbsp;pNTQO&nbsp;:=&nbsp;TNtQueryObject(GetProcAddress(GetModuleHandle(NtDllName),&nbsp;'NtQueryObject'));<br>&nbsp;&nbsp;if(@pNTQO&nbsp;&lt;&gt;&nbsp;nil)&nbsp;then<br>&nbsp;&nbsp;begin<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dwSize&nbsp;:=&nbsp;sizeof(OBJECT_NAME_INFORMATION);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;New(pObjectInfo);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Windows.ZeroMemory(pObjectInfo,&nbsp;SizeOf(pObjectInfo^));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;:=&nbsp;pNTQO(hObject,&nbsp;ObjectNameInformation,&nbsp;pObjectInfo,&nbsp;dwSize,&nbsp;@dwSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;////ret&nbsp;:=&nbsp;NtQueryObject(hObject,&nbsp;ObjectNameInformation,&nbsp;pObjectInfo,&nbsp;dwSize,&nbsp;@dwSize);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///ShowMessage(&nbsp;&nbsp;&nbsp;);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;ret&nbsp;=&nbsp;&nbsp;STATUS_SUCCESS&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;:=&nbsp;WideCharToString(pObjectInfo.Buffer);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;Trim(Result)&nbsp;=&nbsp;''&nbsp;then&nbsp;&nbsp;Result&nbsp;:=&nbsp;SysUtils.SysErrorMessage(Windows.GetLastError);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Dispose(pObjectInfo);<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//<br>&nbsp;&nbsp;end;<br>&nbsp;&nbsp;<br>end;<br><br>//==========================<br>//调用<br>//哈哈,这个方法不光是检查串口,所有的句柄对像都实用.包括Socket句柄<br>var<br>&nbsp;&nbsp;DeviceName:&nbsp;string;<br>&nbsp;&nbsp;<br>begin<br>&nbsp;&nbsp;try<br>&nbsp;&nbsp;&nbsp;&nbsp;Result&nbsp;:=&nbsp;0;<br>&nbsp;&nbsp;&nbsp;&nbsp;DeviceName&nbsp;:=&nbsp;NtDll.GetObjectName(hFile);<br>&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(Length(DeviceName)&nbsp;&gt;=&nbsp;17)and(&nbsp;Pos('device/serial',&nbsp;AnsiLowerCase(DeviceName))&nbsp;&gt;&nbsp;0)&nbsp;then<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ShowMessage('有效的串口句柄')<br>&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ShowMessage(无效的串口句柄')
 
我回去试试看楼上的方法
 
楼上的方法在Vista下不好用啊,不管怎么样都是“操作成功完成”
 
这不是你写的程序问题,应该是USB串口的驱动写得不好造成的,换个USB串口吧<br><br>造成蓝屏现象一般由Ring0级程序引起的,Ring3级的应用程序在windows&nbsp;NT以后的系统中运行,顶多也就程序崩溃,不会出现楼主所说的蓝屏
 
我最近也在学习驱动程序,正和楼上的有同感
 
多人接受答案了。
 
后退
顶部