There is a powerful service manager in Windows NT, which manages a part of the background process that implements important features, such as ftp.http.ras. Network Message, these background processes are called services, they can start in the system When loading, you can run in a higher priority, which can be said to be a very close to the system's core device driver. Windows95 does not provide a Service Manager, replacing a simple registration interface, you can be similar For the service under Windows 95 (but strictly speaking, there is no service in Windows 95), the same, through this registration interface, we can make your own program to start with the system and run, and finally stop, and operation with the system The system is combined to achieve many unique features. First we can first take a look at some related knowledge.
Process Database (PDB) Introduction
In the core data structure of Windows, there is an important process management structure called the process database, which is located in the public memory stack of the Kernel32, which can be pointed to the structure via getCurrentProcessId (...), the following is the composition of the partial PDB, The service logo byte at the PDB shift 21h is related to this article. By analyzing the following pseudo code, we can clearly see the so-called service process under Windows 95 or Windows 98, but it is only the corresponding PDB This sign word is set to 1.
Offset length description
==============================================
00h DWORD TYPE / / KERNEL32 object type
04h dword creference // reference count
08h DWORD UN1 // unknown
0CH DWORD PSOMEEVENT / / Point to K32OBJ_EVENT pointer
10h DWORD TERMINATIONSTATUS / / Event Sign or Return Value
14h DWORD UN2 // unknown
...
21h Byte Flags1 // Service tag,
// "1" is a service process,
// "0" ordinary process
...
24h DWORD PPSP // DOS PSP pointer
...
==============================================
Implement interface
(1) The simple service interface provided in Windows 95 is a 32-bit API: RegisterServiceProcess, because the author has to be reversed in this API because there is no exact interpretation of this API in the VC Online Help, the author has to make reverse analysis of this API. The following is In Windows95's false code of the API in the Kernel32.dll. We can clearly see how the Window95 is doing, and it is actually very simple.
Bool RegisterServiceProcess (DWORD DWPROCESSID, DWORD DWTYPE) {
Handle dwpid;
IF (dwprocessid == NULL)
DWPID = dwcurrentprocessid; // Get Global Kernel32 Variable
Else
// Call Some Kernel Functions
IF ((dwpid = checkpid (dwprocessid) == NULL)
Return False;
IF (dwtype == 1)
{
* (BYTE *) (DWPID 0x21) | = 0x01;
Return True;
}
IF (dwtype == 0)
{
* (BYTE *) (DWPID 0x21) & = 0xfe;
Return True;
}
Return False;
}
The following is the function of the function:
Bool RegisterServiceProcess (DWORD DWPID, DWORD DWTYPE)
Parameters: DWPID: Process ID, NULL represents the current process
DWTYPE: RSP_SIMPLE_SERVICE is registration
Rsp_unregister_service is unregistered
Return Value: True: Call success
FALSE: Call failed
(2) In addition, in order to let the service process will have the opportunity to start after boot, the load method is provided in the REGISTRY of Windows 95: adding its own application line to Key "mycomputer / hkey_local_machine / software / currentversion / runservices". You can realize the boot automatic loading. Of course, if you have no such key in the machine, you can build one.
Routine
---- The following is the implementation routine, all the code has been tested, which can be easily added to your project file.
---- head File:
// file: service.h
// the head file of "service.cpp"
// NOTE: 1. You Must USE C Compiler
// 2. The Platform Is Win32 (WinNT & WIN95)
#ifndef _Service_H
#define_service_h
/// use for Win95 Service
// micros
#define rsp_simple_service 1
#define rsp_unregister_service 0
// Function Types for getProcAddress
#define registerServiceProcess_profile (DWORD (__stdcall *) (DWORD, DWORD))
// service fuctions in Win95
Bool W95ServiceRegister (DWORD DWTYPE);
BOOL W95StartService (DWORD DWTYPE);
#ENDIF
CPP file:
// file: service.cpp --- Implement The Service
#include "service.h"
/// use for Win95 Service
Registered as a Service subroutine:
/
// define: Bool W95ServiceRegister (dWord dwtype) // Parameters: dwtype --- Flag to register or unregister the service
// RSP_SIMPLE_SERVICE Means Register
// rsp_unregister_service means unregister
// Return: True --- Call Success; false --- Call Failer
BOOL W95SERVICEREGISTER (DWORD DWTYPE)
{
// Function Address defination
DWORD (__stdcall * hookregisterServiceProcess)
DWORD DWPROCESSID, DWORD DWTYPE);
// Get Address of Function
HookRegisterServiceProcess = registerServiceProcess_profile
GetProcaddress
(GetModuleHandle ("kernel32"),
Text ("RegisterServiceProcess")));
// register the win95 service
HookRegisterServiceProcess (NULL, DWTYPE) == 0)
Return False;
Return True;
}
Join the registry program:
#define service_name text ("service")
// define: BOOL W95StartService (DWORD DWTYPE)
// parameters: dwtype --- Flag to register or unregister the service
// RSP_SIMPLE_SERVICE Means Register
// rsp_unregister_service means unregister
// Return: True --- Call Success; false --- Call Failer
BOOL W95StartService (DWORD DWTYPE)
{
// Local Variables
TCHAR LPSZBUFF [256];
LPTSTR LPSZSTR = LPSZBUFF 128;
LPTSTR LPSZNAME = LPSZBUFF;
Handle hkey = null;
DWORD DWSTRCB = 0;
DWORD DWVALUETYPE = 0;
// Get Service Name Currently
LPSZNAME = getcommandline ();
For (int i = _tcslen (lpszname) -1; i> = 0; I -)
{
IF ((LPSZNAME [I]! = ') && (LPSZNAME [I]! =')))
Break;
ELSE IF (LPSZNAME [I] == '")
LPSZNAME [I] = '/ 0';
}
IF (LPSZNAME [0] == '") lpszname = lpszname 1;
// registe as start up service
IF (REGOPENKEYEX (HKEY_LOCAL_MACHINE,
Text ("Software // Microsoft // Windows // CurrentVersion // RunServices"),
0,
Key_Query_Value | Key_Set_Value,
& hkey)! = Error_Success)
{
IF (REGCREATEKEY (HKEY_LOCAL_MACHINE,
Text ("Software // Microsoft // Windows // CurrentVersion // RunServices"),
& hkey)! = Error_Success)
{
// debugout ("RegcreateKey () Error!");
Return False;
}
}
DWVALUETYPE = REG_SZ;
DWSTRCB = 128;
// Take Value
IF (RegQueryValueex (HKEY,
Service_name,
0,
& dwvalueType,
(Lpbyte) LPSZSTR,
& dwstrcb) == Error_Success)
{
// Find this key value
IF (_TCSCMP (LPSZSTR, LPSZNAME) == 0)
{
// Remove the service
IF (dwtype == rP_unregister_service)
{
IF (regdeletevalue (hkey, service_name) == Error_Success)
{
RegcloseKey (HKEY);
Return True;
}
RegcloseKey (HKEY);
Return False;
}
// Already Exist Service
IF (dwtype == rP_simple_service)
{
// debugout ("Already Registed!");
RegcloseKey (HKEY);
Return True;
}
}
// not find it
} // no this value
// unregiste return
IF (dwtype == rP_unregister_service)
{
RegcloseKey (HKEY);
Return True;
}
// no this value thr
IF (dwtype == rP_simple_service)
{
DWSTRCB = 128;
// SET VALUE
IF (RegSetValueex (HKEY,
Service_name,
0,
REG_SZ,
(Const Byte *) LPSZNAME,
DWSTRCB)! = Error_Success)
{
// debugout ("RegSetValueex () Error!");
RegcloseKey (HKEY);
Return False;
}
RegcloseKey (HKEY);
Return True;
}
// unknow type
RegcloseKey (HKEY);
Return False;
}
Main program: // WinMain function is The entry of the this program
Int apientry Winmain (Hinstance Hinstance,
Hinstance Hprevinstance,
LPSTR LPCMDLINE,
INT ncmdshow)
{
IF (W95ServiceRegister (RSP_SIMPLE_SERVICE))
{
W95StartService (RSP_SIMPLE_SERVICE);
}
MessageBox (Null, "Sample Service", "Service", MB_OK;
Unreferenced_parameter (Hinstance);
Unreferenced_parameter (lpcmdline);
Unreferenced_parameter (ncmdshow);
Unreferenced_Parameter (HPREVINSTANCE);
Return 0;
}
Run this program, wait until MessageBox pop-up, exit from Windows to the LOG ON status, you will see MessageBox keep open until the response or system is turned off.