[线程][运行][线程]关于线程运行和线程内核对象的关系

08月 31st, 2008 by admin
Posted in VC/MFC | No Comments »

每个线程都有其内核对象,内核对象中有对线程引用的计数。当用GetCurrentThread()等函数或取线程句柄时,计数就会增加;当用CloseHandle()释放线程句柄时,计数就减少。计数减为0时,内核对象就被释放。

那么这个内核对象的计数和线程的运行有什么关系?
若计数减为0时,线程还没运行完,系统会怎么处理?

引用 1 楼 jasonshark 的回复:
有两个计数,一个是CloseHandle可以减掉的,这个是HandleCount,另外还有一个总的PointerCount = HandleCount + ReferenceCount, ReferenceCount是内核里使用的,比如Scheduler要调度你的线程,就肯定得拿一个ReferenceCount, 这个是CloseHandle搞不掉的. 内核对象是否被释放看的是总的PointerCount,不是看HandleCount

学习了!

GetCurrentThread() 获取的线程句柄 是个伪句柄,并不会增加计数,用CloseHandle来释放这个伪句柄,也不会影响计数。

当内核对象的引用计数为0时,系统会释放内核对象。
线程的内核对象含有 大部分管理该线程的系统信息,如线程的退出码,线程的挂起计数等等。

当线程退出时,会对线程内核对象做如下事情:将内核对象的状态变为有信号,设置线程的退出码,引用计数减1。
内核对象不会被自动释放,除非所有指向该对象的外部指针都已经关闭,也就是说引用计数为0时,才释放。

不会出现“计数减为0时,线程还没运行”的情况。 线程在运行时,计数至少是1

回答的不错。学习了

那我对同一个句柄多次掉用closeHandle(),会有什么结果。HandleCount 会变为负的么?那PointerCount也有可能变成0了。

不会,CloseHandle以后句柄就失效了,也就没有从Handle到object的映射关系了,再CloseHandle会返回错误的. 这里说的都是实句柄, 伪句柄就更没关系了

Tags: ,

[win98][开发][运行]难道win98下vc开发的不能在xp下运行

08月 29th, 2008 by admin
Posted in VC/MFC | No Comments »

再问个问题 我在win98下用vc6做了个东西 在win98下也能很好的运行 但把它考到xp下就功能就不正常了
这种情况怎么解决呢

这个程序主要是用来 对一个网站投票用的.每隔5秒 分布点屏幕上两个坐标.
下面是代码
#include <windows.h>
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
POINT            pt,pt_a[3] ;
int i=0;
BOOL f,f2=TRUE;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
    static TCHAR szAppName[] = TEXT ("vm") ;
    HWND        hwnd;
    MSG          msg;
    WNDCLASS    wndclass ;
   
    wndclass.style        = CS_HREDRAW &brvbar CS_VREDRAW ;
    wndclass.lpfnWndProc  = WndProc ;
    wndclass.cbClsExtra    = 0 ;
    wndclass.cbWndExtra    = 0 ;
    wndclass.hInstance    = hInstance ;
    wndclass.hIcon        = NULL ;
    wndclass.hCursor      = LoadCursor (NULL, IDC_ARROW) ;
    wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
    wndclass.lpszMenuName  = NULL ;
    wndclass.lpszClassName = szAppName ;
   
    if (!RegisterClass (&wndclass))
    {
          MessageBox (NULL, TEXT ("Program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
    }
   
    hwnd = CreateWindow (szAppName, TEXT ("vm"),
                          WS_OVERLAPPED &brvbar WS_CAPTION &brvbar WS_SYSMENU &brvbar WS_BORDER,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          200, 100,
                          NULL, NULL, hInstance, NULL) ;
   
    ShowWindow (hwnd, iCmdShow) ;
    UpdateWindow (hwnd) ;
   
    while (GetMessage (&msg, NULL, 0, 0))
    {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
    }
    return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HDC              hdc ;
    PAINTSTRUCT      ps ;
     
TCHAR          szBuffer [16] ;

    switch (message)
    {
    case WM_CREATE:
          SetTimer(hwnd,1,5000,NULL);
          return 0 ;
    case WM_TIMER:
  //在时间间隔里把鼠标移到指定的位置并按鼠标左键;
  if ( f )
  {
  switch (f2)
  {
  case TRUE:
      SetCursorPos (pt_a[0].x,pt_a[0].y);
  mouse_event (MOUSEEVENTF_LEFTDOWN &brvbar MOUSEEVENTF_LEFTUP,0,0,0,0);
  f2=!f2;
  break;
  case FALSE:
    SetCursorPos (pt_a[1].x,pt_a[1].y);
mouse_event (MOUSEEVENTF_LEFTDOWN &brvbar MOUSEEVENTF_LEFTUP,0,0,0,0);
  f2=!f2;
  break;
  }
  }
  InvalidateRect (hwnd, NULL, TRUE) ;
  return 0 ;
    case WM_KEYDOWN:
  switch (wParam)
          {//循环执行的开关
          case VK_HOME:
  f = TRUE ;
  break;
          case VK_END:
  f = FALSE;
  break;
  }
          return 0 ;
    case WM_CHAR:
  GetCursorPos (&pt) ;
  //SendMessage(hwnd,WM_LBUTTONDOWN,MK_LBUTTON,MAKELONG(pt.x,pt.y));
  //把鼠标移动到需要的地方按键盘上任意字母键将该处坐标存储在数组里
  //只能存2个坐标,并在屏幕上显示;
          pt_a[i].x = pt.x;
  pt_a[i].y = pt.y;
  i = i+1;
  InvalidateRect (hwnd, NULL, TRUE) ;
  return 0 ;
    case WM_PAINT:
  hdc = BeginPaint (hwnd, &ps) ;
                  TextOut (hdc,0,0,szBuffer,wsprintf(szBuffer,TEXT("%d  %d"),pt_a[0].x,pt_a[0].y) );
  TextOut (hdc,0,15,szBuffer,wsprintf(szBuffer,TEXT("%d  %d"),pt_a[1].x,pt_a[1].y) );
  EndPaint (hwnd, &ps) ;
          return 0 ;
    case WM_DESTROY :
  KillTimer (hwnd, 1) ;
          PostQuitMessage (0) ;
          return 0 ;
    }
    return DefWindowProc (hwnd, message, wParam, lParam) ;
}

症状就是 打开之后 原先的功能没得了
简单的说就是
以下代码好像没有执行

case WM_CHAR:
  GetCursorPos (&pt) ;
  //把鼠标移动到需要的地方按键盘上任意字母键将该处坐标存储在数组里
  //只能存2个坐标,并在屏幕上显示;
          pt_a[i].x = pt.x;
  pt_a[i].y = pt.y;
  i = i+1;
  InvalidateRect (hwnd, NULL, TRUE) ;
  return 0 ;

你跟一下,难道是xp和98发的消息不一样

谢谢 suilj 实在是抱歉
都是我的错
我按错键盘了 我有两个键盘 放到一起的 晕了
现在试了 没得问题

Tags: , , ,

[VC2005][结合][运行]急!!!怎样才能使VC2005与SDK结合运行windows程序

08月 29th, 2008 by admin
Posted in VC/MFC | No Comments »

我先下了个来装Platform SDK。然后装了VC2005速成版。最后按照
http://msdn.microsoft.com/zh-cn/vstudio/ms235626(VS.80).aspx
进行操作。然后创建工程,输入以下代码:但是最后发现好多宏重定义,特向大家求助。

/*————————————————————————
       
  HELLOWIN.C — Displays "Hello, Windows 98!" in client area
       
                (c) Charles Petzold, 1998
       
———————————————————————–*/
       
#include <windows.h>
       

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
       

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
       
                  PSTR szCmdLine, int iCmdShow)
       
{
       
    static TCHAR szAppName[] = TEXT ("HelloWin") ;
       
    HWND  hwnd ;
       
    MSG    msg ;
       
    WNDCLASS wndclass ;
       

  wndclass.style        = CS_HREDRAW &brvbar CS_VREDRAW ;
       
  wndclass.lpfnWndProc  = WndProc ;
       
    wndclass.cbClsExtra  = 0 ;
       
    wndclass.cbWndExtra  = 0 ;
       
    wndclass.hInstance    = hInstance ;
       
    wndclass.hIcon        = LoadIcon (NULL, IDI_APPLICATION) ;
       
  wndclass.hCursor      = LoadCursor (NULL, IDC_ARROW) ;
       
  wndclass.hbrBackground= (HBRUSH) GetStockObject (WHITE_BRUSH) ;
       
  wndclass.lpszMenuName  = NULL ;
       
    wndclass.lpszClassName= szAppName ;
       

    if (!RegisterClass (&wndclass))
       
    {
       
            MessageBox (  NULL, TEXT ("This program requires Windows NT!"),
       
                                  szAppName, MB_ICONERROR) ;
       
            return 0 ;
       
    }
       
    hwnd = CreateWindow( szAppName,      // window class name
       
                  TEXT ("The Hello Program"),  // window caption
       
                  WS_OVERLAPPEDWINDOW,  // window style
       
                  CW_USEDEFAULT,// initial x position
       
                  CW_USEDEFAULT,// initial y position
       
                  CW_USEDEFAULT,// initial x size
       
                  CW_USEDEFAULT,// initial y size
       
                  NULL,                // parent window handle
       
              NULL,            // window menu handle
       
              hInstance,  // program instance handle
       
              NULL) ;      // creation parameters
       
 
       
    ShowWindow (hwnd, iCmdShow) ;
       
    UpdateWindow (hwnd) ;
       
 
       
    while (GetMessage (&msg, NULL, 0, 0))
       
    {
       
            TranslateMessage (&msg) ;
       
          DispatchMessage (&msg) ;
       
    }
       
    return msg.wParam ;
       
}

啥工程?

先装VC,后装SDK。

你可以试试手动改一下VC的选项,在“项目和解决方案”—“VC++目录”里面调整一下包含文件、库文件的目录次序,把SDK的目录移到前面。

Tags: , , ,

[hook][系统][运行]如何hook系统运行所有进程中的writefile函数

08月 28th, 2008 by admin
Posted in VC/MFC | No Comments »

需要写一个监视文件变化的程序,系统中其他程序要不停的向一个文件中写入数据,我需要在每次写入数据是截获写入的内容,并且通过网络发送出来。
通过网上查一些资料,发现hook api函数writefile比较适合,并下载了一个hook messageboxa函数的例程。

源码邮箱地址:whereissky@163.com  psw:123456abc

但该例程只能hook在exe文件中的messageboxa函数,如果我把exe源文件中的messagebox函数删掉,安装钩子。

同时单独新建工程,在工程中调用messagebox函数显示对话框,运行时就截获不到messagebox中的数据

难道该hook只对安装调用进程有效?如何修改才能对系统目前运行的所有进程所有程序中的messagebox函数都有效呢?

各位大虾帮忙看看,多谢了!

做一个DLL,把Hook函数写在DLL里面,再设法让所有进程加载这个DLL,方法有很多,可以在网上搜索一下,不过都有缺陷。

例程代码中已经设定最后一个参数为0了,但还是不行

引用 1 楼 greatws 的回复:
SetWindowHookEx函数的最后一个参数设为0,就是全局注入,不过只能注入有消息循环的进程

如何让所有进程加载这个服务?能否说得详细一点儿?

引用 2 楼 cnzdgs 的回复:
做一个DLL,把Hook函数写在DLL里面,再设法让所有进程加载这个DLL,方法有很多,可以在网上搜索一下,不过都有缺陷。

我认为比较好的方法是:把注册表HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWindows键的AppInit_DLLs值中加入你的DLL的名称及路径,这样进程在启动时会自动加载这个DLL。

我在源码基础上改成hook writefile,采用这种方法加载后现象很奇怪。
我做了一个测试程序,用writefile写1.txt文件到c:,经过我的处理过程后写文件到2.txt。测试程序调用writefile写1.txt文件到c盘后,只有打开1.txt才能产生2.txt文件,不知道为什么,
有时间的话帮忙看看,谢谢了

源码地址:whereissky@163.com
密码:123456abc

引用 5 楼 cnzdgs 的回复:
我认为比较好的方法是:把注册表HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionWindows键的AppInit_DLLs值中加入你的DLL的名称及路径,这样进程在启动时会自动加载这个DLL。

方法很多, 像楼上所说的, 但要考虑下杀毒软件的感受, 呵.

不是说在ring3用什么什么也可以绕过copy-on-write机制?

要看你的代码是怎么写的。

这里好像不能用附件

代码在163邮箱中
源码地址:whereissky@163.com
密码:123456abc

引用 9 楼 cnzdgs 的回复:
要看你的代码是怎么写的。

要进行全局的HOOK
还是用SSDT HOOK
挂NtWriteFile

看了你的代码,处理逻辑比较乱,不知道你想实现什么。
你在Hook函数中先关掉了要写的文件,这样做了之后的后果是无法预料的,因为调用者不知道这个句柄被关闭了,后面还会用这个句柄继续操作,如果进程再创建其它句柄,有可能得到与该句柄相同的值,这样会导致以后的操作转到了后打开的句柄上;如果进程没有再创建其它句柄,则对此句柄的操作都会失败(除了WriteFile)。
接下来你有以只写、非共享方式打开了2.txt,而且最后没有关闭,这样下次创建就会失败。
如果你想把写文件的内容都记录到2.txt中,可以在Hook函数中打开2.txt,将文件指针调整到最后,把缓冲区中的数据写进去,再关闭2.txt,然后调用原WriteFile函数,如果不想让进程写原文件,可以用SetLastError设置错误码,并返回失败。
如果你要对某一个或某些特定文件来Hook,需要Hook CreateFile函数来判断要打开的文件,并把句柄值记录下来,再在WriteFile中判断句柄值来确定是否要执行Hook操作。

这种东西建议在Ring0用文件过滤驱动,如果在ring3级放出去估计没有杀软不报你病毒的

我要监视硬盘上的写文件操作,文件名和路径可以固定。
一个应用程序不断的向文件中写入数据,我需要在写入数据的同时hook到并把最新的数据通过网络发送出来:(

你是要Hook一个进程还是要Hook所有进程?是只处理一个文件还是处理所有文件?

一个就行,名字固定,就是不知道这种情况能不能hook到……

原本还想hook所有,选择特定文件处理的

只要是应用基本上都是可以Hook到的,不过你应该再Hook一下CreateFile,当程序打开目标文件时,将句柄记录下来,在WriteFile中判断句柄值与记录的相同时再做处理。

我试试看,真是谢谢了

在数控系统试了一下,没有成功。
在计算机上可以拦截到,在数控系统所在的windowsxp上也可以拦截到。数控系统启动后采用写入文件指令将数据写入到文件中,拦截失败。
运行数控程序,用nc的write指令写文件的时候,被写入文件自动被加载到数控系统nc内存中,该文件在本地硬盘上不可见。当数控程序运行完毕,此时被写入文件仍处于加载状态,只有通过手动方式进行卸载(不能自动卸载)后,该文件在硬盘上才可见。

不知道nc采用什么样的保护机制和写入动作,这种情况有什么其他的办法?

还是采用RING0下实现吧

先确认一下,文件是在运行过程中就写入磁盘的,还是在卸载的时候才建立的?如果看不出来可以借助其它工具分析一下,例如FileMon。另外这个数控系统有没有驱动程序?如果它用驱动程序来写文件,在用户级是无法Hook到的,只能做在内核级来处理。不过对于没有驱动程序开发经验的人来说,做驱动程序是很难的,少说也要几个月时间。

用ifs,文件过滤驱动,你提到的FileMon就是这样做的。

用filemon试了一下,连它都不行。

filemon运行后,启动数控系统,系统内编辑数控程序用write命令写文件,数控程序运行完毕后,系统显示被写入文件处于被加载状态,filemon没有任何反应。

运行filemon还有一个副作用,此时数控系统内部的程序不能打开和修改,就连加载也不行了。此时手动卸载文件不成功,系统报错。只能把filemon停掉,然后重启系统才可正常运行。

还有比filemon更厉害的软件么?不知道数控系统都做了哪些保护,彻底晕了……

Tags: , , ,

[编译][运行][结果]编译运行的结果和执行生成的.exe文件的结果不一样

08月 27th, 2008 by admin
Posted in VC/MFC | No Comments »

有个VC程序,我想在菜单上添加一个菜单。可是当编译运行的后还是和原来的菜单项一样,没有出现我新添加的菜单项。
然而当我在Debug文件夹里运行.exe文件的时候我新添加的菜单项怎么又存在了呢?
请问各位大侠是不是我的VC软件有问题啊?还是其它什么原因呢?
万分感谢!

关键是我在编译运行后没有出现我想要的结果,而在debug下的exe执行的结果却是符合的。
为什么我在菜单中增加的选项在编译运行后没有出现我想要的结果呢?

看一下输出路径和执行的路径是否相同,我以前也遇到过。

输出的EXE不是最新的,另外看看版本debug 还是 release,它们也有不同的地方

Tags: , , ,

[运行]MFC运行问题

08月 4th, 2008 by admin
Posted in VC/MFC | No Comments »

程序已经做完了,点击DEBUG文件夹下的.exe 可以运行 但是我通过QQ把它传给别人时就不行了,别人打不开,这到底是怎么回事啊?

首先你应该用release版的
其次是不是使用动态编译的?有类库依赖?

更名了吗?是不是用到什么资源没有传给他!

程序运行时有两种方式,
一种是Share Dll,
一种是Static Library,
如果楼主是用第一种的话,
别人电脑上可能没装VC,
所以运行时缺少相应的库文件,
如果改成第二种,
文件会相应大一些,
但是可以在不装VC等相关编译环境的机器上运行,

引用 4 楼 miaoshengwu 的回复:
程序运行时有两种方式,
一种是Share Dll,
一种是Static Library,
如果楼主是用第一种的话,
别人电脑上可能没装VC,
所以运行时缺少相应的库文件,
如果改成第二种,
文件会相应大一些,
但是可以在不装VC等相关编译环境的机器上运行,

别人的机器上缺少必要的运行时库

如果使用VC6 可以用VC带的工具"C:Program FilesMicrosoft Visual StudioCOMMONToolsDEPENDS.EXE"查看需要哪些文件;
若使用VC2005还是建议使用静态链接“Use MFC in a Static Library”

我是用VS2005做的,怎样静态编译啊?

project->properties->configuration properties->general:右侧的use of mfc 选in a static library

Tags: ,

[在线][求救][运行]【在线求救】为什么我在运行我的程序的时候当我关闭后但是进程kill不了呢

07月 27th, 2008 by admin
Posted in VC/MFC | No Comments »

小弟写了一个关于对话框的小东西,
但是每次我关闭后,但是我那小东
西的进程确没有关闭!请知情人士
给点建议!

引用 1 楼 cnzdgs 的回复:
这可能的原因就多了,可以用F5运行程序,在关闭之后,点击VC工具栏的break按钮,根据调用堆栈查看当前正在执行哪里的代码。
对于简单的程序,最常见的可能原因是程序还在执行消息循环,有两种常见情况:一种是创建了非模态对话框,窗口关闭时没有PostQuitMessage;另一种是在应用程序类的InitInstance函数中DoModel,但最后是用return TRUE返回,应该用return FALSE。

老大我现在好像就是创建非模态对话框,那如果是这个问题的话我要如何解决呢?我是个菜鸟!能否给个例子,我参考呢?谢谢

响应WM_CLOSE消息,调用DestroyWindow;再响应WM_DESTROY消息,调用PostQuitMessage。

不是直接加个PostQuitMessage (0) ;???

可以

真的可以了耶 谢谢啦

Tags: , , ,

[处理][程序][运行]怎么处理程序运行中的意外错误

07月 19th, 2008 by admin
Posted in VC/MFC | No Comments »

怎么处理程序运行中的意外错误?

引用 1 楼 hua_yang 的回复:
try
{
}
catch()
{
}

捕捉异常
try
{
}
catch()
{
}

每一句都写?

try
{
}
catch()
{
}
当然,还要在里面添加代码了
你想处理什么异常。是在哪一块代码会出现异常那里写啊。

try
{
}
catch()
{
}

try
{
// 这里写可能发生异常的代码,也可以是函数调用
// 只要在这里面执行的代码产生的异常,绝大部分是可以捕获的
// 极少数严重异常捕获不到
// 如果需要,可以再嵌套使用try—catch,也可以在调用的函数里面嵌套使用。
}
catch(…)
{
// 这里写捕获异常后的处理代码
}

try/catch是c++语言的异常处理功能;也可以用操作系统的SEH(结构化异常处理)功能,具体看MSDN。

引用 3 楼 rocker9527 的回复:
捕捉异常
try
{
}
catch()
{
}

当然不是。在你认为有可能出现异常的地方,如:打开文件,要判断文件是否存在等。

try
{
}
catch()
{
} 只是捕捉异常的地方,最终的还是要解决为什么会有异常

try
{
}
catch()
{
}
放在你觉得可能会发生异常的地方,这个得凭经验和知识。

引用 11 楼 scq2099yt 的回复:
try
{
}
catch()
{
}
放在你觉得可能会发生异常的地方,这个得凭经验和知识。
好啊

setjmp;setlongjmp

Tags: , , ,

[运行][程序][错误]运行程序时出现一个错误。

06月 19th, 2008 by admin
Posted in VC/MFC | No Comments »

=========

提示如上图。

执行win32控制程序不会报错。

执行以前建立好的应用程序也不会错。

但是新建一个MFC程序,执行的话,就会报这个错误,

然后VC6.0直接关闭。

你的VC6有问题,换个别的版本,或者是你电脑中毒了

.。。。。。

我上午还好好的,

下午突然变这样了。。。。。。

[Quote=引用   2   楼   king820802   的回复:]
你的VC6有问题,换个别的版本,或者是你电脑中毒了
[/Quote]

看来是中毒了,杀毒去吧

果然是瑞星防火墙问题。。。。。。。。。。。。
把瑞星防火墙卸载了,就好用了。

以前一直开着瑞星杀毒,瑞星防火墙,360实施保护,360防火墙

10分钟后结贴。.回复内容太短了!

Tags: , , ,

[运行]vc++6.0运行问题

06月 13th, 2008 by admin
Posted in VC/MFC | No Comments »

result CXX0030: Error: expression cannot be evaluated
运行后老是有这样的问题出现,请问是为什么呢

出现了不能识别的定义

具体实例看以下
http://topic.csdn.net/u/20070802/15/eabfb7db-fef1-4c22-9cae-fa98a347517e.html

Tags: ,