📄 ntse95cf.c
字号:
/****************************************************************************
NT-Service helper library.
SCM Emulation on Win95.
Configuring the services.
Copyright (c) 2000,2002 Timofei Bondarenko.
****************************************************************************/
#include <windows.h>
#include <winsvc.h>
#include <stdlib.h>
#include "ntse.h"
#include "ntsepriv.h"
//#define BUFKEYNAME (128)
#define BUFKEYVALUE (272) /* In real, both limit are 255 in 98/98/ME */
/* Placing into "RunServices" is sufficient to start service,
but it will not appear in taskbar...
AUTO-start can be implemented by writing to both keys:
Service is actually started via "RunServices" and then
inserted into taskbar by its own reinvocation via "Run".
For DEMAND-start we simply put it in "Run".
Summary: AUTO should be in at least "RunServices",
then it will replicate itself to "Run".
DEMAND may be in "Run" only.
On another hand, you may decide not to place it in taskbar at all...
Then no to write it to "Run" group.
*/
static const char ntseRegRunAUTO[] =
"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices";
static const char ntseRegRunDEMAND[] =
"Software\\Microsoft\\Windows\\CurrentVersion\\Run";
#if 1
#define RegCrOpenKey(path, rights, phk) \
RegCreateKeyEx(HKEY_LOCAL_MACHINE, (path), 0, /*NULL*/"", 0, (rights), NULL, (phk), NULL)
#else
#define RegCrOpenKey(path, rights, phk) \
RegOpenKeyEx(HKEY_LOCAL_MACHINE, (path), 0, (rights), (phk))
#endif
static int ntseReadKey(const char *path, const char *name, char *buf, unsigned size)
{
int rv;
HKEY hk;
DWORD len = size;
/*KEY_READ | KEY_WRITE*/
rv = RegCrOpenKey(path, KEY_QUERY_VALUE, &hk);
if (!rv)
{
rv = RegQueryValueEx(hk, name, NULL, NULL, buf, &len);
RegCloseKey(hk);
if (buf && size) buf[size-1] = '\0';
}
UL_DEBUG((NSLOG, "%!l ntseReadKey95(%s::%s)=%s", rv, path, name,
!rv && buf && size? buf: ""));
return rv;
}
static int ntseWriteKey(const char *path, const char *name, const char *buf)
{
int rv;
HKEY hk;
rv = RegCrOpenKey(path, KEY_SET_VALUE, &hk);
if (!rv)
{
rv = RegSetValueEx(hk, name, 0, REG_SZ, buf, strlen(buf)+1);
RegCloseKey(hk);
}
UL_DEBUG((NSLOG, "%!l ntseWriteKey95(%s::%s)=%s", rv, path, name, buf));
return rv;
}
static int ntseDeleteKey(const char *path, const char *name)
{
int rv;
HKEY hk;
rv = RegCrOpenKey(path, KEY_SET_VALUE, &hk);
if (!rv)
{
rv = RegDeleteValue(hk, name);
RegCloseKey(hk);
}
UL_DEBUG((NSLOG, "%!l ntseDeleteKey95(%s::%s)", rv, path, name));
// if (rv == ERROR_FILE_NOT_FOUND) rv = 0;
return rv;
}
int ntseCreate95(ntseContext *nc,
const char *serviceName, /* name of service */
int serviceType, /* type of service: */
int startType, /* when to start service */
const char *commandline) /* name of binary file */
{
int rv;
if (!serviceName || !commandline)
{
rv = ERROR_INVALID_PARAMETER;
goto Return;
}
if (!(serviceType & SERVICE_WIN32))
{
rv = ERROR_CALL_NOT_IMPLEMENTED;
goto Return;
}
if (0 == ntseReadKey(ntseRegRunAUTO, serviceName, NULL, 0) ||
0 == ntseReadKey(ntseRegRunDEMAND, serviceName, NULL, 0))
{
rv = ERROR_SERVICE_EXISTS;
goto Return;
}
switch(startType)
{
case SERVICE_AUTO_START:
rv = ntseWriteKey(ntseRegRunAUTO, serviceName, commandline);
ntseWriteKey(ntseRegRunDEMAND, serviceName, commandline); /* optional */
break;
case SERVICE_DEMAND_START:
ntseDeleteKey(ntseRegRunAUTO, serviceName);
rv = ntseWriteKey(ntseRegRunDEMAND, serviceName, commandline);
break;
case SERVICE_DISABLED:
rv = 0;
break;
default:
rv = ERROR_CALL_NOT_IMPLEMENTED;
break;
}
Return:
if (rv)
UL_INFO((NSLOG, "%!l ntseCreate95(%s) FAILED", rv, serviceName));
else UL_TRACE((NSLOG, "%!l ntseCreate95(%s) Finished", rv, serviceName));
return rv;
}
int ntseChange95(ntseContext *nc,
const char *serviceName, /* name of service */
int serviceType, /* type of service: */
int startType, /* when to start service */
const char *commandline) /* name of binary file */
{
int rv;
char ocmd[BUFKEYVALUE];
int starttype;
if (!serviceName)
{
rv = ERROR_INVALID_PARAMETER;
goto Return;
}
if (!(serviceType & SERVICE_WIN32) &&
serviceType != SERVICE_NO_CHANGE)
{
rv = ERROR_CALL_NOT_IMPLEMENTED;
goto Return;
}
starttype = SERVICE_AUTO_START;
rv = ntseReadKey(ntseRegRunAUTO, serviceName, ocmd, sizeof(ocmd));
if (rv && rv != ERROR_MORE_DATA)
{
starttype = SERVICE_DEMAND_START;
rv = ntseReadKey(ntseRegRunDEMAND, serviceName, ocmd, sizeof(ocmd));
if (rv && rv != ERROR_MORE_DATA)
{
rv = ERROR_SERVICE_DOES_NOT_EXIST;
goto Return;
}
}
if (startType == SERVICE_NO_CHANGE)
startType = starttype;
if (rv && !commandline &&
startType != SERVICE_DISABLED &&
startType != starttype) goto Return;
if (commandline) rv = 0;
else commandline = ocmd;
switch(startType)
{
case SERVICE_AUTO_START:
if (rv)
{
if (startType == starttype) rv = 0;
break;
}
rv = ntseWriteKey(ntseRegRunAUTO, serviceName, commandline);
ntseWriteKey(ntseRegRunDEMAND, serviceName, commandline);
break;
case SERVICE_DEMAND_START:
if (rv)
{
if (startType == starttype) rv = 0;
break;
}
rv = ntseWriteKey(ntseRegRunDEMAND, serviceName, commandline);
if (!rv)
{
rv = ntseDeleteKey(ntseRegRunAUTO, serviceName);
if (rv == ERROR_FILE_NOT_FOUND) rv = 0;
}
break;
case SERVICE_DISABLED:
rv = ntseDelete95(serviceName);
break;
default:
rv = ERROR_CALL_NOT_IMPLEMENTED;
break;
}
Return:
if (rv)
UL_INFO((NSLOG, "%!l ntseChange95(%s) FAILED", rv, serviceName));
else UL_TRACE((NSLOG, "%!l ntseChange95(%s) Finished", rv, serviceName));
return rv;
}
int ntseQueryConf95(ntseContext *nc, const char *name, QUERY_SERVICE_CONFIG **cfg)
{
char ocmd[BUFKEYVALUE];
int starttype, rv;
if (cfg) *cfg = NULL;
starttype = SERVICE_AUTO_START;
rv = ntseReadKey(ntseRegRunAUTO, name, ocmd, sizeof(ocmd));
if (rv && rv != ERROR_MORE_DATA)
{
starttype = SERVICE_DEMAND_START;
rv = ntseReadKey(ntseRegRunDEMAND, name, ocmd, sizeof(ocmd));
if (rv && rv != ERROR_MORE_DATA)
{
rv = ERROR_SERVICE_DOES_NOT_EXIST;
goto Return;
}
}
if (cfg)
{
QUERY_SERVICE_CONFIG *sc;
sc = (QUERY_SERVICE_CONFIG*)malloc(strlen(ocmd) + 1 +
sizeof(QUERY_SERVICE_CONFIG) );
if (!sc)
{
rv = ERROR_NOT_ENOUGH_MEMORY;
goto Return;
}
memset(sc, 0, sizeof(QUERY_SERVICE_CONFIG));
sc->dwStartType = starttype;
sc->dwServiceType = SERVICE_WIN32_OWN_PROCESS;
sc->lpBinaryPathName = (char*)&sc[1];
strcpy((char*)&sc[1], ocmd);
sc->dwErrorControl = SERVICE_ERROR_IGNORE;
*cfg = sc;
}
rv = 0;
Return:
if (rv)
UL_INFO((NSLOG, "%!l ntseQueryConf95(%s) FAILED", rv, name));
else UL_TRACE((NSLOG, "%!l ntseQueryConf95(%s) Finished", rv, name));
return rv;
}
int ntseDelete95(const char *name)
{
int rv0, rv1;
rv0 = ntseDeleteKey(ntseRegRunAUTO, name);
rv1 = ntseDeleteKey(ntseRegRunDEMAND, name);
if (rv0 == ERROR_FILE_NOT_FOUND ||
rv1 != ERROR_FILE_NOT_FOUND && rv0 == 0) rv0 = rv1;
if (rv0 == ERROR_FILE_NOT_FOUND)
rv0 = ERROR_SERVICE_DOES_NOT_EXIST;
if (rv0)
UL_INFO((NSLOG, "%!l ntseDelete95(%s) FAILED", rv0, name));
else UL_TRACE((NSLOG, "%!l ntseDelete95(%s) Finished", rv0, name));
return rv0;
}
int ntseAutoRun95(ntseContext *nc, const char *name, const char *commandline)
{
return commandline? ntseWriteKey(ntseRegRunDEMAND, name, commandline)
: ntseDeleteKey(ntseRegRunDEMAND, name);
}
/* end of ntse_95cf.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -