4/5 (8 avis)
Vue 7 849 fois - Téléchargée 873 fois
#define _WIN32_WINNT 0x0500 // Pour Windows 2000 et supérieur #include <windows.h> // Déclarations globales: HINSTANCE hDll; SERVICE_STATUS_HANDLE hServiceStatusHandle; SERVICE_STATUS ServiceStatus; HANDLE hEvent,hFile; char buff[MAX_PATH]; // Fonction d'installation du service: int WINAPI InstallService() { HKEY hkService,hkSvchost; SC_HANDLE schScm ,schService; char* pData; DWORD dwError=0, dwLen,dwSize = 0; // Ouvrir le gestionnaire de services: schScm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if(schScm) { // Créer notre service: schService = CreateService(schScm, "RacppService", 0, SERVICE_ALL_ACCESS, SERVICE_WIN32_SHARE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, "%SystemRoot%\\System32\\svchost.exe -k netsvcs", 0, 0, 0, 0, 0); if(schService) { // Ajouter une description à notre service: SERVICE_DESCRIPTION sd; sd.lpDescription = "Service dans une DLL lancé par svchost.exe"; ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &sd); // Ajouter la sous-clé Parameters à la clé de notre service: RegCreateKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\RacppService\\Parameters", 0, 0, REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS, 0, &hkService, 0); // Récupérer le chemin complet de notre Dll: GetModuleFileName(hDll, buff, sizeof(buff)); // Affecter le chemin de la Dll à la sous-clé Parameters sous le nom ServiceDll: RegSetValueEx(hkService, "ServiceDll", 0, REG_EXPAND_SZ, (BYTE*)buff, lstrlen(buff)+1); // Fermer la clé de notre service: RegCloseKey(hkService); // Ouvrir la clé indiquant la liste des groupes d'instances de svchost.exe: RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost", 0, KEY_ALL_ACCESS, &hkSvchost); // Obtenir la longueur du contenu du groupe netsvcs: RegQueryValueEx(hkSvchost, "netsvcs", 0, 0, 0, &dwSize); // Fixer le nom de notre service pour la liste des services du groupe netsvcs: lstrcpy(buff,"RacppService"); dwLen=lstrlen(buff); // Allouer la mémoire nécessaire pour la nouvelle liste des noms de services du groupe netsvcs: pData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSize + dwLen + 1); if(pData) { char *pNames; // Récupérer la liste des noms de services du groupe netsvcs: RegQueryValueEx(hkSvchost, "netsvcs", 0, 0, (BYTE*)pData, &dwSize); // Vérifier si le nom existe for (pNames = pData; *pNames; pNames=strchr(pNames,0)+1) if(!lstrcmpi(pNames, buff)) break; // L'ajouter s'il n'existe pas: if (*pNames == 0) { memcpy(pData + dwSize - 1, buff, dwLen + 1); RegSetValueEx(hkSvchost, "netsvcs", 0, REG_MULTI_SZ, (BYTE*)pData, dwSize + dwLen + 1); } else dwError=ERROR_ALREADY_EXISTS; // Libérer la mémoire allouée: HeapFree(GetProcessHeap(),0,pData); } else dwError=ERROR_NOT_ENOUGH_MEMORY; // Fermer la clé svchost: RegCloseKey(hkSvchost); // Fermer le handle de notre service: CloseServiceHandle(schService); } // Fermer le handle du gestionnaire de services: CloseServiceHandle(schScm); } // Retourner dwError si non nul, sinon GetLastError(): return dwError? dwError : GetLastError(); } // Fonction de désinstallation du service: DWORD WINAPI RemoveService() { HKEY hkSvchost; SC_HANDLE schScm ,schService; char* pData; DWORD dwError=0,dwSize = 0; // Ouvrir le gestionnaire de services: schScm = OpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS); if(schScm) { // Ouvrir notre service: schService=OpenService(schScm,"RacppService",SERVICE_ALL_ACCESS); if(schService) { // Supprimer le service: if(DeleteService(schService)) { // Ouvrir la clé indiquant la liste des groupes d'instances de svchost.exe: RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost", 0, KEY_ALL_ACCESS, &hkSvchost); // Obtenir la longueur du contenu du groupe netsvcs: RegQueryValueEx(hkSvchost, "netsvcs", 0, 0, 0, &dwSize); // Fixer le nom de notre service pour la liste des services du groupe netsvcs: lstrcpy(buff,"RacppService"); // Allouer la mémoire nécessaire pour tous les noms de services du groupe netsvcs: pData=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,dwSize); if(pData) { char *pNames; // Récupérer la liste des noms de services du groupe netsvcs: RegQueryValueEx(hkSvchost, "netsvcs", 0, 0, (BYTE*)pData, &dwSize); // Vérifier si le nom existe: for (pNames = pData; *pNames; pNames=strchr(pNames,0)+1) if(!lstrcmpi(pNames,buff)) break; // Le supprimer s'il existe: if (*pNames) { char* pNext; pNext=strchr(pNames,0)+1; memcpy(pNames,pNext,dwSize-(pNext-pData)); RegSetValueEx(hkSvchost, "netsvcs", 0, REG_MULTI_SZ, (BYTE*)pData, dwSize -(lstrlen(buff)+1)); } else dwError=ERROR_NO_SUCH_MEMBER; // Libérer la mémoire allouée: HeapFree(GetProcessHeap(),0,pData); } else dwError=ERROR_NOT_ENOUGH_MEMORY; // Fermer la clé svchost: RegCloseKey(hkSvchost); } // Fermer le handle de notre service: CloseServiceHandle(schService); } // Fermer le handle du gestionnaire de services: CloseServiceHandle(schScm); } // Retourner dwError si non nul, sinon GetLastError(): return dwError? dwError : GetLastError(); } // Fonction HandlerEx communiquant avec le gestionnaire de services: DWORD WINAPI HandlerEx(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext) { switch(dwControl) { case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_SHUTDOWN: // Mettre le service à l'état "En cours d'arrêt": ServiceStatus.dwWaitHint = 1000; ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; SetServiceStatus(hServiceStatusHandle, &ServiceStatus ); // Mettre l'Event à l'état signalé: SetEvent(hEvent); return NO_ERROR; default: ServiceStatus.dwWaitHint = 0; break; } SetServiceStatus(hServiceStatusHandle, &ServiceStatus);// Obligatoire selon MSDN return NO_ERROR; } // Fonction Callback appelée toutes les minutes notre timer: VOID CALLBACK TimerProc( LPVOID lpParameter,BOOLEAN TimerOrWaitFired) { SYSTEMTIME st; DWORD dwLen; // Se positionner à la fin du fichier log: SetFilePointer(hFile,0,0,FILE_END); // Former la ligne à écrire dans le fichier log: lstrcpy(buff,"Le timer de RacppService a été déclenché le "); GetLocalTime(&st); GetDateFormat(0,0,&st,"dd/MM/yyyy",buff+lstrlen(buff),12); lstrcat(buff," à "); GetTimeFormat(0,0,&st,"HH:mm:ss",buff+lstrlen(buff),12); lstrcat(buff,"\r\n"); // Ecrire la ligne formée dans le fichier log: WriteFile(hFile,buff,lstrlen(buff),&dwLen,0); return; } // ServiceMain VOID WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) { hServiceStatusHandle = RegisterServiceCtrlHandlerEx("RacppService", HandlerEx, NULL); if (hServiceStatusHandle) { // Initialiser notre structure SERVICE_STATUS: ServiceStatus.dwServiceType = SERVICE_WIN32; ServiceStatus.dwControlsAccepted = 0; ServiceStatus.dwWin32ExitCode = 0; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwCheckPoint = 0; // Mettre le service dans l'état "En cours de démarrage": ServiceStatus.dwWaitHint = 1000; ServiceStatus.dwCurrentState = SERVICE_START_PENDING; SetServiceStatus(hServiceStatusHandle, &ServiceStatus); // Créer un Event avec "non signalé" comme état initial: hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (hEvent) { // Ouvrir notre fichier log ou le créer si inexistant: hFile=CreateFile("C:\\racppservice.log", GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, 0, 0); if(hFile!=INVALID_HANDLE_VALUE) { // Créer et lancer notre timer: HANDLE hTimerQueue,hTimer; hTimerQueue=CreateTimerQueue(); CreateTimerQueueTimer(&hTimer,hTimerQueue,TimerProc,0,0,60000,WT_EXECUTEINTIMERTHREAD); // Mettre le service dans l'état "Démarré": ServiceStatus.dwWaitHint = 0; ServiceStatus.dwCurrentState = SERVICE_RUNNING; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ; SetServiceStatus(hServiceStatusHandle, &ServiceStatus); // Attendre que l'Event soit à l'état signalé: WaitForSingleObject(hEvent, INFINITE); // Détruire notre timer: DeleteTimerQueueTimer(hTimerQueue,hTimer,0); DeleteTimerQueueEx(hTimerQueue,0); // Fermer le handle de notre fichier log: CloseHandle(hFile); } // Fermer le handle de l'Event: CloseHandle(hEvent); } // Mettre le service dans l'état "Arrêté": ServiceStatus.dwWaitHint = 0; ServiceStatus.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(hServiceStatusHandle, &ServiceStatus); } return; } // DllMain BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpReserved) { // Obtenir le HINSTANCE de notre dll: hDll=hInst; return TRUE; }
6 mai 2010 à 12:02
Mon expérience NT 4 a été très intéressante car je l'ai faite avec un HDD de récupération (provenant d'un poste client) qui n'avait pas été formaté et sortait d'un lot venant d'une grosse entreprise que je ne nommerai pas.
Par un coup de hasard extraordinaire, il se trouvait que ma machine avait la même config hard que la machine d'où provenait le HDD.
Ce qui fait que, mettant tout cela en marche, j'ai eu la bonne surprise de constater que NT se lançait !!!
J'en ai donc profité pour tenter le coup de prendre la main sur le login et sur l'administration. Et j'y suis arrivé relativement assez vite....
en restant évidemment hors connexion... J'ai aussi utilisé win 2000 pro sur poste client. Il est encore installé sur une machine que je mets en marche de temps en temps mais que je n'utilise pas vraiment.
Moralité : la meilleure façon de formater un HDD déclassé... c'est la massette !
3 mai 2010 à 23:47
3 mai 2010 à 20:28
J'utilise encore accessoirement XP SP3.et j'ai aussi laissé tombé mes bricolages Bart PE parce que, tout compte fait, tout cela ne rimait à rien.
Administrer oui... mais un OS qui est suffisamment transparent pour avancer en connaissances.
Donc, petit à petit (j'ai dû commencer il y a une dizaine d'années) je suis passé à Linux. Voilà donc pour ce qui est des mains de néophyte... et je suis entièrement d'accord avec toi pour dire que le pire qui puisse arriver à un OS c'est qu'il permette à quiconque d'être, en permanence, utilisateur privilégié.
Je te prie de m'accorder le fait que je n'ai jamais autrement avancé que par une pratique quotidienne et non par des acquis théoriques qui, il faut le reconnaître, sont utiles pour moins perdre de temps.
30 avril 2010 à 22:35
28 avril 2010 à 16:07
enfin bon.... j'utilise de moins en moins win.
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.