📄 dbgthrd.c
字号:
goto failed;
}
}
if( service_manager != NULL ) {
ENUM_SERVICE_STATUS *eenum = NULL;
DWORD bytesNeeded;
DWORD servicesReturned;
DWORD resumeHandle = 0;
EnumServicesStatus( service_manager, SERVICE_WIN32 + SERVICE_DRIVER,
SERVICE_ACTIVE + SERVICE_INACTIVE,
NULL, 0, &bytesNeeded, &servicesReturned,
&resumeHandle );
if( servicesReturned == 0 ) {
eenum = calloc( 1, bytesNeeded );
if( eenum == NULL ) {
rc = FALSE;
goto failed;
}
EnumServicesStatus( service_manager, SERVICE_WIN32 + SERVICE_DRIVER,
SERVICE_ACTIVE + SERVICE_INACTIVE,
eenum, bytesNeeded, &bytesNeeded,
&servicesReturned, &resumeHandle );
for( i = 0; i < servicesReturned; ++i ) {
strlwr( eenum[i].lpServiceName );
strlwr( eenum[i].lpDisplayName );
}
strlwr( service_name );
for( i = 0; i < servicesReturned; ++i ) {
if( strcmp( eenum[i].lpServiceName, service_name ) == 0 ) {
service_name = eenum[i].lpServiceName;
goto done;
}
}
for( i = 0; i < servicesReturned; ++i ) {
if( strcmp( eenum[i].lpDisplayName, service_name ) == 0 ) {
service_name = eenum[i].lpServiceName;
goto done;
}
}
for( i = 0; i < servicesReturned; ++i ) {
if( strstr( eenum[i].lpServiceName, service_name ) != 0 ) {
service_name = eenum[i].lpServiceName;
goto done;
}
}
for( i = 0; i < servicesReturned; ++i ) {
if( strstr( eenum[i].lpDisplayName, service_name ) != 0 ) {
service_name = eenum[i].lpServiceName;
goto done;
}
}
}
done:
service = OpenService( service_manager, service_name,
SERVICE_ALL_ACCESS );
if( service == NULL ) {
AddMessagePrefix( "Unable to open the specified service", 0 );
rc = FALSE;
goto failed;
}
free( eenum );
}
if( service != NULL ) {
if( ControlService( service, SERVICE_CONTROL_STOP, &status ) ) {
i = 0;
for( ;; ) {
if( i == 40 ) {
AddMessagePrefix( "Unable to stop the specified service",
0 );
Shared.err = ERROR_SERVICE_REQUEST_TIMEOUT;
goto failed;
}
if( !QueryServiceStatus( service, &status ) ) {
AddMessagePrefix( "Unable to stop the specified service",
0 );
rc = FALSE;
goto failed;
}
if( status.dwCurrentState == SERVICE_STOPPED )
break;
Sleep( 500 );
++i;
}
}
}
if( dll_name[0] && dll_destination[0] ) {
char *end;
WIN32_FIND_DATA dat;
strcpy( buff, dll_destination );
end = buff + strlen( buff ) - 1;
if( *end != '\\' && *end != '/' ) {
strcat( buff, "\\" );
}
strcat( buff, "." );
if( FindFirstFile( buff, &dat ) != INVALID_HANDLE_VALUE ) {
if( dat.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
_splitpath( dll_name, NULL, NULL, fname, ext );
_makepath( buff, NULL, dll_destination, fname, ext );
dll_destination = buff;
}
}
if( !CopyFile( dll_name, dll_destination, FALSE ) ) {
AddMessagePrefix( "Unable to copy '", 3000 );
strcat( MsgPrefix, dll_name );
strcat( MsgPrefix, "' to '" );
strcat( MsgPrefix, dll_destination );
strcat( MsgPrefix, "'" );
rc = FALSE;
goto failed;
}
}
if( service != NULL ) {
char const *parm[2];
parm[0] = service_parm;
parm[1] = NULL;
StartService( service, 0, parm );
i = 0;
for( ;; ) {
if( i == 40 ) {
AddMessagePrefix( "Unable to start the specified service", 0 );
Shared.err = ERROR_SERVICE_REQUEST_TIMEOUT;
goto failed;
}
if( !QueryServiceStatus( service, &status ) ) {
AddMessagePrefix( "Unable to start the specified service", 0 );
rc = FALSE;
goto failed;
}
if( status.dwCurrentState == SERVICE_RUNNING )
break;
Sleep( 500 );
++i;
}
CloseServiceHandle( service );
Sleep( 1000 ); // just in case it's slow!
}
if( service_manager != NULL ) {
CloseServiceHandle( service_manager );
}
if( Shared.pid == -1 ) {
mod = LoadLibrary( "PView.dll" );
if( mod != NULL ) {
select = ( SELECTPROCESS )GetProcAddress( mod, "_SelectProcess@4" );
if( select != NULL ) {
if( Shared.name == NULL || Shared.name[0] == '\0' ) {
Shared.pid = ( *select ) ( "" );
} else {
i = 0;
for( ;; ) {
if( i == 10 ) {
Shared.pid = ( *select ) ( "" );
break;
}
Shared.pid = ( *select ) ( Shared.name );
if( Shared.pid != NULL && Shared.pid != -1 ) {
break;
}
Sleep( 500 );
++i;
}
}
}
}
CloseHandle( mod );
}
if( Shared.pid != NULL && Shared.pid != -1 ) {
rc = MyDebugActiveProcess( Shared.pid );
if( IsWOW ) {
/*
* WOW was already running, so we start up wowdeb (this
* is used in debugging WOW, provided with NT), and
* then we do a "CreateProcess" on the WOW app. Since WOW
* is already running, this doesn't really create a process,
* but instead has the existing WOW start the 16-bit task.
*/
memset( &sinfo, 0, sizeof( sinfo ) );
sinfo.cb = sizeof( sinfo );
sinfo.wShowWindow = SW_NORMAL;
rc = CreateProcess( NULL, /* application name */
"wowdeb.exe", /* command line */
NULL, /* process attributes */
NULL, /* thread attributes */
TRUE, /* inherit handles */
0, /* creation flags */
NULL, /* environment block */
NULL, /* starting directory */
&sinfo, /* startup info */
&pinfo /* process info */
);
rc = CreateProcess( NULL, /* application name */
Shared.name, /* command line */
NULL, /* process attributes */
NULL, /* thread attributes */
TRUE, /* inherit handles */
0, /* creation flags */
NULL, /* environment block */
NULL, /* starting directory */
&sinfo, /* startup info */
&pinfo /* process info */
);
}
pinfo.dwProcessId = Shared.pid;
} else {
memset( &sinfo, 0, sizeof( sinfo ) );
sinfo.cb = sizeof( sinfo );
sinfo.wShowWindow = SW_NORMAL;
rc = CreateProcess( NULL, /* application name */
Shared.name, /* command line */
NULL, /* process attributes */
NULL, /* thread attributes */
TRUE, /* inherit handles */
Shared.flags, /* creation flags */
NULL, /* environment block */
NULL, /* starting directory */
&sinfo, /* startup info */
&pinfo /* process info */
);
}
failed:
SetErrorMode( oldErrorMode );
Shared.pid = pinfo.dwProcessId;
return( rc );
}
static BOOL DoWaitForDebugEvent( void )
{
BOOL done;
DWORD code;
BOOL rc;
done = FALSE;
UseVDMStuff = FALSE;
while( !done ) {
SetLastError( 0 );
if( WaitForDebugEvent( &DebugEvent, INFINITE ) ) {
rc = TRUE;
DidWaitForDebugEvent = TRUE;
if( DebugEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT ) {
code = DebugEvent.u.Exception.ExceptionRecord.ExceptionCode;
#ifdef WOW
if( code == STATUS_VDM_EVENT ) {
BOOL vdmrc;
vdmrc = pVDMProcessException( &DebugEvent );
if( vdmrc ) {
UseVDMStuff = TRUE;
done = TRUE;
} else {
LastDebugEventTid = DebugEvent.dwThreadId;
DoContinueDebugEvent( DBG_CONTINUE );
}
/*
* sometimes, we seem to get crap back, so the thing to do
* is to ignore it. When all else fails, punt.
*/
} else
#endif
{
switch( code ) {
case STATUS_DATATYPE_MISALIGNMENT:
case STATUS_BREAKPOINT:
case STATUS_SINGLE_STEP:
case STATUS_ACCESS_VIOLATION:
case STATUS_IN_PAGE_ERROR:
case STATUS_NO_MEMORY:
case STATUS_ILLEGAL_INSTRUCTION:
case STATUS_NONCONTINUABLE_EXCEPTION:
case STATUS_INVALID_DISPOSITION:
case STATUS_ARRAY_BOUNDS_EXCEEDED:
case STATUS_FLOAT_DENORMAL_OPERAND:
case STATUS_FLOAT_DIVIDE_BY_ZERO:
case STATUS_FLOAT_INVALID_OPERATION:
case STATUS_FLOAT_OVERFLOW:
case STATUS_FLOAT_STACK_CHECK:
case STATUS_FLOAT_UNDERFLOW:
case STATUS_INTEGER_DIVIDE_BY_ZERO:
case STATUS_INTEGER_OVERFLOW:
case STATUS_PRIVILEGED_INSTRUCTION:
case STATUS_STACK_OVERFLOW:
case STATUS_CONTROL_C_EXIT:
done = TRUE;
break;
default:
if( ( code & ERROR_SEVERITY_ERROR ) ==
ERROR_SEVERITY_ERROR ) {
done = TRUE;
break;
}
LastDebugEventTid = DebugEvent.dwThreadId;
DoContinueDebugEvent( DBG_EXCEPTION_NOT_HANDLED );
break;
}
}
} else {
done = TRUE;
}
} else {
rc = FALSE;
break;
}
}
return( rc );
}
static void StopDebuggee( void )
{
if( DebugeePid != NULL && ( IsWOW || !DebugeeEnded ) ) {
/*
* we must process debug events until the process is actually
* terminated
*/
Slaying = TRUE;
if( IsWin32s ) {
DoContinueDebugEvent( DBG_TERMINATE_PROCESS );
DoWaitForDebugEvent();
DoContinueDebugEvent( DBG_CONTINUE );
} else {
HANDLE hp;
hp = OpenProcess( PROCESS_ALL_ACCESS, FALSE, DebugeePid );
if( hp != NULL ) {
TerminateProcess( hp, 0 );
CloseHandle( hp );
while( !( DebugExecute( 0, NULL, FALSE ) & COND_TERMINATE ) ) {
}
/*
* we must continue the final debug event for everything to
* be truly clean and wonderful
*/
DoContinueDebugEvent( DBG_CONTINUE );
}
}
Slaying = FALSE;
}
DebugeePid = NULL;
}
// end of seperate thread
DWORD StartControlThread( char *name, DWORD *pid, DWORD cr_flags )
{
Shared.pid = *pid;
Shared.flags = cr_flags;
Shared.name = name;
Shared.control_thread_running = FALSE;
if( !IsWin32s ) {
DWORD tid;
Shared.requestsem = CreateSemaphore( NULL, 0, 1, NULL );
Shared.requestdonesem = CreateSemaphore( NULL, 0, 1, NULL );
Shared.hThread = CreateThread( NULL, 0,
( LPTHREAD_START_ROUTINE )ControlFunc, NULL, 0, &tid );
if( Shared.hThread == NULL ) {
MessageBox( NULL, "Error creating thread!", TRP_The_WATCOM_Debugger,
MB_APPLMODAL + MB_OK );
}
Shared.control_thread_running = TRUE;
}
ControlReq( CTL_START );
*pid = Shared.pid;
return( Shared.err );
}
/*
* MyWaitForDebugEvent - wait for a debug event. Only return meaningful
* VDM debug events
*/
BOOL MyWaitForDebugEvent( void )
{
if( Shared.on_control_thread ) {
return( DoWaitForDebugEvent() );
}
ControlReq( CTL_WAIT );
return( Shared.rc );
}
void MyContinueDebugEvent( int continue_how )
{
if( Shared.on_control_thread ) {
DoContinueDebugEvent( continue_how );
return;
}
Shared.how = continue_how;
ControlReq( CTL_CONTINUE );
}
void StopControlThread( void )
{
ControlReq( CTL_STOP );
if( Shared.control_thread_running ) {
WaitForSingleObject( Shared.hThread, INFINITE );
CloseHandle( Shared.requestsem );
CloseHandle( Shared.requestdonesem );
Shared.control_thread_running = FALSE;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -