|
|
1.1 ! root 1: /****************************************************************************\ ! 2: * INCLUDES, DEFINES ! 3: \****************************************************************************/ ! 4: #define STRICT ! 5: #include <windows.h> ! 6: #include <stdio.h> ! 7: #include <stdlib.h> ! 8: ! 9: #define PERR(api) printf("\n%s: Error %d from %s on line %d", \ ! 10: __FILE__, GetLastError(), api, __LINE__); ! 11: #define PMSG(msg) printf("\n%s line %d: %s", \ ! 12: __FILE__, __LINE__, msg); ! 13: ! 14: // this event is signalled when the ! 15: // worker thread ends ! 16: // ! 17: HANDLE hServDoneEvent = NULL; ! 18: SERVICE_STATUS ssStatus; // current status of the service ! 19: ! 20: SERVICE_STATUS_HANDLE sshStatusHandle; ! 21: DWORD dwGlobalErr; ! 22: DWORD TID = 0; ! 23: HANDLE threadHandle = NULL; ! 24: HANDLE pipeHandle; ! 25: ! 26: ! 27: /****************************************************************************\ ! 28: * FUNCTION PROTOTYPES ! 29: \****************************************************************************/ ! 30: ! 31: VOID service_main(DWORD dwArgc, LPTSTR *lpszArgv); ! 32: VOID service_ctrl(DWORD dwCtrlCode); ! 33: BOOL ReportStatusToSCMgr(DWORD dwCurrentState, ! 34: DWORD dwWin32ExitCode, ! 35: DWORD dwCheckPoint, ! 36: DWORD dwWaitHint); ! 37: VOID die(char *reason); ! 38: VOID worker_thread(VOID *notUsed); ! 39: VOID StopSimpleService(LPTSTR lpszMsg); ! 40: BOOL WriteSD_ToA_File(PSECURITY_DESCRIPTOR psdAbsoluteSD, LPTSTR lpszFileName); ! 41: ! 42: ! 43: /****************************************************************************\ ! 44: * GLOBAL VARIABLES AND TYPEDEFS ! 45: \****************************************************************************/ ! 46: ! 47: #define SZ_SD_BUF 100 ! 48: #define SZ_SID_BUF 75 ! 49: #define SZ_ACL_BUF 150 ! 50: ! 51: UCHAR ucAbsSDBuf [SZ_SD_BUF] = ""; ! 52: UCHAR ucEvrSDBuf [SZ_SD_BUF] = ""; ! 53: UCHAR ucSIDBuf [SZ_SID_BUF] = ""; ! 54: UCHAR ucPwrUsrsSIDBuf [SZ_SID_BUF] = ""; ! 55: UCHAR ucACLBuf [SZ_ACL_BUF] = ""; ! 56: ! 57: DWORD dwSID = SZ_SID_BUF; ! 58: DWORD dwDACL = SZ_ACL_BUF; ! 59: BOOL bFloppiesAreLocked; ! 60: ! 61: PSECURITY_DESCRIPTOR psdAbsoluteSD = (PSECURITY_DESCRIPTOR)&ucAbsSDBuf; ! 62: PSECURITY_DESCRIPTOR psdEveryoneSD = (PSECURITY_DESCRIPTOR)&ucEvrSDBuf; ! 63: PSID psidAdministrators = (PSID)&ucSIDBuf; ! 64: PSID psidPowerUsers = (PSID)&ucPwrUsrsSIDBuf; ! 65: PACL pNewDACL = (PACL)&ucACLBuf; ! 66: ! 67: ! 68: ! 69: ! 70: // main() -- ! 71: // all main does is call StartServiceCtrlDispatcher ! 72: // to register the main service thread. When the ! 73: // API returns, the service has stopped, so exit. ! 74: // ! 75: VOID ! 76: main() ! 77: { ! 78: SERVICE_TABLE_ENTRY dispatchTable[] = { ! 79: { TEXT("SimpleService"), (LPSERVICE_MAIN_FUNCTION)service_main }, ! 80: { NULL, NULL } ! 81: }; ! 82: ! 83: #define FILE_TO_REDIRECT_STDOUT_TO "c:\\floplock.out" ! 84: freopen(FILE_TO_REDIRECT_STDOUT_TO,"w+",stdout); ! 85: ! 86: if (!StartServiceCtrlDispatcher(dispatchTable)) { ! 87: StopSimpleService("StartServiceCtrlDispatcher failed."); ! 88: } ! 89: } ! 90: ! 91: ! 92: ! 93: // service_main() -- ! 94: // this function takes care of actually starting the service, ! 95: // informing the service controller at each step along the way. ! 96: // After launching the worker thread, it waits on the event ! 97: // that the worker thread will signal at its termination. ! 98: // ! 99: VOID ! 100: service_main(DWORD dwArgc, LPTSTR *lpszArgv) ! 101: { ! 102: DWORD dwWait; ! 103: SECURITY_ATTRIBUTES sa; ! 104: ! 105: // register our service control handler: ! 106: // ! 107: sshStatusHandle = RegisterServiceCtrlHandler( ! 108: TEXT("SimpleService"), ! 109: service_ctrl); ! 110: ! 111: if (!sshStatusHandle) ! 112: goto cleanup; ! 113: ! 114: // SERVICE_STATUS members that don't change in example ! 115: // ! 116: ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ! 117: ssStatus.dwServiceSpecificExitCode = 0; ! 118: ! 119: ! 120: // report the status to Service Control Manager. ! 121: // ! 122: if (!ReportStatusToSCMgr( ! 123: SERVICE_START_PENDING, // service state ! 124: NO_ERROR, // exit code ! 125: 1, // checkpoint ! 126: 3000)) // wait hint ! 127: goto cleanup; ! 128: ! 129: // create the event object. The control handler function signals ! 130: // this event when it receives the "stop" control code. ! 131: // ! 132: hServDoneEvent = CreateEvent( ! 133: NULL, // no security attributes ! 134: TRUE, // manual reset event ! 135: FALSE, // not-signalled ! 136: NULL); // no name ! 137: ! 138: if (hServDoneEvent == (HANDLE)NULL) ! 139: goto cleanup; ! 140: ! 141: // report the status to the service control manager. ! 142: // ! 143: if (!ReportStatusToSCMgr( ! 144: SERVICE_START_PENDING, // service state ! 145: NO_ERROR, // exit code ! 146: 2, // checkpoint ! 147: 3000)) // wait hint ! 148: goto cleanup; ! 149: ! 150: // Create a security descriptor that allows only local Administrators ! 151: // to do anything with the pipe. Since Domain administrators are ! 152: // normally also local Administrators, this will serve most needs ! 153: ! 154: /************************************************************************\ ! 155: * ! 156: * Get SID of local Administrators ! 157: * ! 158: \************************************************************************/ ! 159: ! 160: { ! 161: #define SZ_DOMAIN_BUF 40 ! 162: #define SZ_PSNU_BUF 8 ! 163: UCHAR ucDomainBuf [SZ_DOMAIN_BUF] = ""; ! 164: UCHAR ucPSNUBuf [SZ_PSNU_BUF] = ""; ! 165: ! 166: DWORD dwDomainName = SZ_DOMAIN_BUF; ! 167: ! 168: LPSTR lpszDomain = (LPSTR)&ucDomainBuf; ! 169: PSID_NAME_USE psnuType = (PSID_NAME_USE)&ucPSNUBuf; ! 170: ! 171: if(!LookupAccountName((LPSTR)NULL, /* local name */ ! 172: "Administrators", ! 173: psidAdministrators, ! 174: &dwSID, ! 175: lpszDomain, ! 176: &dwDomainName, ! 177: psnuType)) ! 178: { StopSimpleService("LookupAccountName"); ! 179: } ! 180: ! 181: if (*psnuType != SidTypeAlias) ! 182: { StopSimpleService("LookupAccountName returned the wrong SID type"); ! 183: } ! 184: } ! 185: ! 186: /************************************************************************\ ! 187: * ! 188: * Get SID of Power Users ! 189: * ! 190: \************************************************************************/ ! 191: ! 192: { ! 193: UCHAR ucDomainBuf [SZ_DOMAIN_BUF] = ""; ! 194: UCHAR ucPSNUBuf [SZ_PSNU_BUF] = ""; ! 195: ! 196: DWORD dwDomainName = SZ_DOMAIN_BUF; ! 197: ! 198: LPSTR lpszDomain = (LPSTR)&ucDomainBuf; ! 199: PSID_NAME_USE psnuType = (PSID_NAME_USE)&ucPSNUBuf; ! 200: ! 201: if(!LookupAccountName((LPSTR)NULL, /* local name */ ! 202: "Power Users", ! 203: psidPowerUsers, ! 204: &dwSID, ! 205: lpszDomain, ! 206: &dwDomainName, ! 207: psnuType)) ! 208: { StopSimpleService("LookupAccountName"); ! 209: } ! 210: ! 211: if (*psnuType != SidTypeAlias) ! 212: { StopSimpleService("LookupAccountName returned the wrong SID type"); ! 213: } ! 214: } ! 215: ! 216: /************************************************************************\ ! 217: * ! 218: * Initialize new DACL ! 219: * ! 220: \************************************************************************/ ! 221: ! 222: if (!InitializeAcl(pNewDACL, ! 223: dwDACL, ! 224: ACL_REVISION2)) ! 225: { StopSimpleService("InitializeAcl"); ! 226: } ! 227: ! 228: /************************************************************************\ ! 229: * ! 230: * Allow All access for local Administrators only ! 231: * ! 232: \************************************************************************/ ! 233: ! 234: if (!AddAccessAllowedAce(pNewDACL, ! 235: ACL_REVISION2, ! 236: FILE_ALL_ACCESS, ! 237: psidAdministrators)) ! 238: { StopSimpleService("AddAccessAllowedAce"); ! 239: } ! 240: ! 241: /************************************************************************\ ! 242: * ! 243: * If we unlock the floppies when the service stops, then for the sake of ! 244: * consistency, we have to also allow Power Users on the Admin-only DACL, ! 245: * since Power Users can stop services. It would be inconsistent to try ! 246: * to lock Power Users away from their floppies if Power Users could get ! 247: * to the floppies simply by stopping the service ! 248: * ! 249: * It's still OK to use the same DACL for the pipe as for the floppies, ! 250: * that is, it's OK to let Power Users on the DACL for the pipe too. The ! 251: * reason is that it is not generally (and certainly not by default) the ! 252: * case that an account is a member of Power Users on more than their own ! 253: * machines. So, putting Power Users on the pipe let's Power Users admin ! 254: * the floppies via the pipe only on the machines on which they are ! 255: * actually Power Users, and again, on those machines they can stop the ! 256: * floppy-locking service as well ! 257: * ! 258: \************************************************************************/ ! 259: ! 260: #define UNLOCK_AT_SERVICE_STOP (0==0) ! 261: if (UNLOCK_AT_SERVICE_STOP) ! 262: { if (!AddAccessAllowedAce(pNewDACL, ! 263: ACL_REVISION2, ! 264: FILE_ALL_ACCESS, ! 265: psidPowerUsers)) ! 266: { StopSimpleService("AddAccessAllowedAce"); ! 267: } ! 268: } ! 269: ! 270: /************************************************************************\ ! 271: * ! 272: * Build SD in absolute format - first the Admins-only then the Everyone SD ! 273: * ! 274: \************************************************************************/ ! 275: ! 276: if (!InitializeSecurityDescriptor(psdAbsoluteSD, ! 277: SECURITY_DESCRIPTOR_REVISION)) ! 278: { StopSimpleService("InitializeSecurityDescriptor"); ! 279: } ! 280: ! 281: if (!InitializeSecurityDescriptor(psdEveryoneSD, ! 282: SECURITY_DESCRIPTOR_REVISION)) ! 283: { StopSimpleService("InitializeSecurityDescriptor"); ! 284: } ! 285: ! 286: /************************************************************************\ ! 287: * ! 288: * Set DACL into SD - first the Admins-only then the Everyone SD ! 289: * ! 290: \************************************************************************/ ! 291: ! 292: if (!SetSecurityDescriptorDacl(psdAbsoluteSD, ! 293: TRUE, // fDaclPresent flag ! 294: pNewDACL, ! 295: FALSE)) // not a default DACL ! 296: { StopSimpleService("SetSecurityDescriptorDacl"); ! 297: } ! 298: ! 299: if (!SetSecurityDescriptorDacl(psdEveryoneSD, ! 300: TRUE, // fDaclPresent flag ! 301: (PACL)NULL, ! 302: FALSE)) // not a default DACL ! 303: { StopSimpleService("SetSecurityDescriptorDacl"); ! 304: } ! 305: ! 306: /************************************************************************\ ! 307: * ! 308: * Check to see that SD is valid before attempting to write it to the file ! 309: * ! 310: \************************************************************************/ ! 311: ! 312: if (!IsValidSecurityDescriptor(psdAbsoluteSD)) ! 313: { StopSimpleService("IsValidSecurityDescriptor"); ! 314: } ! 315: ! 316: sa.nLength = sizeof(sa); ! 317: sa.lpSecurityDescriptor = psdAbsoluteSD; ! 318: sa.bInheritHandle = TRUE; // why not... we spawn no processes ! 319: ! 320: // open our named pipe... ! 321: // ! 322: pipeHandle = CreateNamedPipe( ! 323: "\\\\.\\pipe\\sd_flppy", // name of pipe ! 324: PIPE_ACCESS_DUPLEX, // pipe open mode ! 325: PIPE_TYPE_MESSAGE | ! 326: PIPE_READMODE_MESSAGE | ! 327: PIPE_WAIT, // pipe IO type ! 328: 1, // number of instances ! 329: 0, // size of outbuf (0 == allocate as necessary) ! 330: 0, // size of inbuf ! 331: 1000, // default time-out value ! 332: &sa); // security attributes ! 333: ! 334: if (!pipeHandle) { ! 335: StopSimpleService("CreateNamedPipe"); ! 336: return; ! 337: } ! 338: ! 339: // Set the same DACL onto the floppies ! 340: // ! 341: ! 342: /************************************************************************\ ! 343: * ! 344: * Write SD to file system - first for A: then B: ! 345: * ! 346: \************************************************************************/ ! 347: ! 348: if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\A:")) ! 349: { StopSimpleService("Write of DACL to A: failed"); ! 350: } ! 351: ! 352: if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\B:")) ! 353: { StopSimpleService("Write of DACL to B: failed"); ! 354: } ! 355: ! 356: bFloppiesAreLocked = TRUE; ! 357: ! 358: /************************************************************************\ ! 359: * ! 360: * Works for CDROM drives as well - commented out as this samples is floppy ! 361: * only ! 362: * ! 363: \************************************************************************/ ! 364: /* ! 365: if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\E:")) ! 366: { StopSimpleService("Write of DACL to E: failed"); ! 367: } ! 368: */ ! 369: /************************************************************************\ ! 370: * ! 371: * Works for COM ports as well - commented out as this samples is floppy only ! 372: * ! 373: \************************************************************************/ ! 374: /* ! 375: if (!WriteSD_ToA_File(psdAbsoluteSD,"COM1:")) ! 376: { StopSimpleService("Write of DACL to COM1: failed"); ! 377: } ! 378: */ ! 379: ! 380: // start the thread that performs the work of the service. ! 381: // ! 382: threadHandle = CreateThread( ! 383: NULL, // security attributes ! 384: 0, // stack size (0 means inherit parent's stack size) ! 385: (LPTHREAD_START_ROUTINE)worker_thread, ! 386: NULL, // argument to thread ! 387: 0, // thread creation flags ! 388: &TID); // pointer to thread ID ! 389: ! 390: if (!threadHandle) ! 391: goto cleanup; ! 392: ! 393: // report the status to the service control manager. ! 394: // ! 395: if (!ReportStatusToSCMgr( ! 396: SERVICE_RUNNING, // service state ! 397: NO_ERROR, // exit code ! 398: 0, // checkpoint ! 399: 0)) // wait hint ! 400: goto cleanup; ! 401: ! 402: // wait indefinitely until hServDoneEvent is signaled. ! 403: // ! 404: dwWait = WaitForSingleObject( ! 405: hServDoneEvent, // event object ! 406: INFINITE); // wait indefinitely ! 407: ! 408: cleanup: ! 409: ! 410: if (hServDoneEvent != NULL) ! 411: CloseHandle(hServDoneEvent); ! 412: ! 413: ! 414: // try to report the stopped status to the service control manager. ! 415: // ! 416: if (sshStatusHandle != 0) ! 417: (VOID)ReportStatusToSCMgr( ! 418: SERVICE_STOPPED, ! 419: dwGlobalErr, ! 420: 0, ! 421: 0); ! 422: ! 423: // When SERVICE MAIN FUNCTION returns in a single service ! 424: // process, the StartServiceCtrlDispatcher function in ! 425: // the main thread returns, terminating the process. ! 426: // ! 427: return; ! 428: } ! 429: ! 430: ! 431: ! 432: // service_ctrl() -- ! 433: // this function is called by the Service Controller whenever ! 434: // someone calls ControlService in reference to our service. ! 435: // ! 436: VOID ! 437: service_ctrl(DWORD dwCtrlCode) ! 438: { ! 439: DWORD dwState = SERVICE_RUNNING; ! 440: ! 441: // Handle the requested control code. ! 442: // ! 443: switch(dwCtrlCode) { ! 444: ! 445: // Pause the service if it is running. ! 446: // ! 447: case SERVICE_CONTROL_PAUSE: ! 448: ! 449: if (ssStatus.dwCurrentState == SERVICE_RUNNING) { ! 450: SuspendThread(threadHandle); ! 451: dwState = SERVICE_PAUSED; ! 452: } ! 453: break; ! 454: ! 455: // Resume the paused service. ! 456: // ! 457: case SERVICE_CONTROL_CONTINUE: ! 458: ! 459: if (ssStatus.dwCurrentState == SERVICE_PAUSED) { ! 460: ResumeThread(threadHandle); ! 461: dwState = SERVICE_RUNNING; ! 462: } ! 463: break; ! 464: ! 465: // Stop the service. ! 466: // ! 467: case SERVICE_CONTROL_STOP: ! 468: ! 469: dwState = SERVICE_STOP_PENDING; ! 470: ! 471: // Report the status, specifying the checkpoint and waithint, ! 472: // before setting the termination event. ! 473: // ! 474: ReportStatusToSCMgr( ! 475: SERVICE_STOP_PENDING, // current state ! 476: NO_ERROR, // exit code ! 477: 1, // checkpoint ! 478: 3000); // waithint ! 479: ! 480: if (UNLOCK_AT_SERVICE_STOP) ! 481: { if (!WriteSD_ToA_File(psdEveryoneSD,"\\\\.\\A:")) ! 482: { StopSimpleService("Unlock of A: failed, see log file"); ! 483: } ! 484: if (!WriteSD_ToA_File(psdEveryoneSD,"\\\\.\\B:")) ! 485: { StopSimpleService("Unlock of B: failed, see log file"); ! 486: } ! 487: ! 488: bFloppiesAreLocked = FALSE; ! 489: } ! 490: ! 491: SetEvent(hServDoneEvent); ! 492: return; ! 493: ! 494: // Update the service status. ! 495: // ! 496: case SERVICE_CONTROL_INTERROGATE: ! 497: break; ! 498: ! 499: // invalid control code ! 500: // ! 501: default: ! 502: break; ! 503: ! 504: } ! 505: ! 506: // send a status response. ! 507: // ! 508: ReportStatusToSCMgr(dwState, NO_ERROR, 0, 0); ! 509: } ! 510: ! 511: ! 512: ! 513: // worker_thread() -- ! 514: // this function does the actual nuts and bolts work that ! 515: // the service requires. It will also Pause or Stop when ! 516: // asked by the service_ctrl function. ! 517: // ! 518: VOID ! 519: worker_thread(VOID *notUsed) ! 520: { ! 521: char inbuf[180]; ! 522: char outbuf[180]; ! 523: BOOL ret; ! 524: DWORD bytesRead; ! 525: DWORD bytesWritten; ! 526: DWORD dwLen; ! 527: ! 528: // okay, our pipe has been created, let's enter the simple ! 529: // processing loop... ! 530: // ! 531: while (1) { ! 532: ! 533: // wait for a connection... ! 534: // ! 535: ConnectNamedPipe(pipeHandle, NULL); ! 536: ! 537: // grab whatever's coming through the pipe... ! 538: // ! 539: ret = ReadFile( ! 540: pipeHandle, // file to read from ! 541: inbuf, // address of input buffer ! 542: sizeof(inbuf), // number of bytes to read ! 543: &bytesRead, // number of bytes read ! 544: NULL); // overlapped stuff, not needed ! 545: ! 546: if (!ret) ! 547: // pipe's broken... go back and reconnect ! 548: // ! 549: continue; ! 550: ! 551: switch (inbuf[0]) ! 552: { case 'U': ! 553: dwLen = sprintf(outbuf,"Floppies were unlocked"); ! 554: ! 555: if (!WriteSD_ToA_File(psdEveryoneSD,"\\\\.\\A:")) ! 556: { dwLen += sprintf(outbuf+dwLen,", unlock of A: failed, see log file"); ! 557: } ! 558: if (!WriteSD_ToA_File(psdEveryoneSD,"\\\\.\\B:")) ! 559: { dwLen += sprintf(outbuf+dwLen,", unlock of B: failed, see log file"); ! 560: } ! 561: ! 562: bFloppiesAreLocked = FALSE; ! 563: break; ! 564: ! 565: case 'L': ! 566: dwLen = sprintf(outbuf,"Floppies were locked"); ! 567: ! 568: if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\A:")) ! 569: { dwLen += sprintf(outbuf+dwLen,", lock of A: failed, see log file"); ! 570: } ! 571: if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\B:")) ! 572: { dwLen += sprintf(outbuf+dwLen,", lock of B: failed, see log file"); ! 573: } ! 574: ! 575: bFloppiesAreLocked = TRUE; ! 576: break; ! 577: ! 578: case 'Q': ! 579: if (bFloppiesAreLocked) ! 580: { sprintf(outbuf,"Floppy status is: Locked"); ! 581: } ! 582: else ! 583: { sprintf(outbuf,"Floppy status is: Unlocked"); ! 584: } ! 585: break; ! 586: ! 587: default : ! 588: sprintf(outbuf,"Bad operation passed in"); ! 589: } ! 590: ! 591: // send it back out... ! 592: // ! 593: ret = WriteFile( ! 594: pipeHandle, // file to write to ! 595: outbuf, // address of output buffer ! 596: sizeof(outbuf), // number of bytes to write ! 597: &bytesWritten, // number of bytes written ! 598: NULL); // overlapped stuff, not needed ! 599: ! 600: if (!ret) ! 601: // pipe's broken... go back and reconnect ! 602: // ! 603: continue; ! 604: ! 605: // drop the connection... ! 606: // ! 607: DisconnectNamedPipe(pipeHandle); ! 608: } ! 609: } ! 610: ! 611: ! 612: ! 613: // utility functions... ! 614: ! 615: ! 616: ! 617: // ReportStatusToSCMgr() -- ! 618: // This function is called by the ServMainFunc() and ! 619: // ServCtrlHandler() functions to update the service's status ! 620: // to the service control manager. ! 621: // ! 622: BOOL ! 623: ReportStatusToSCMgr(DWORD dwCurrentState, ! 624: DWORD dwWin32ExitCode, ! 625: DWORD dwCheckPoint, ! 626: DWORD dwWaitHint) ! 627: { ! 628: BOOL fResult; ! 629: ! 630: // Disable control requests until the service is started. ! 631: // ! 632: if (dwCurrentState == SERVICE_START_PENDING) ! 633: ssStatus.dwControlsAccepted = 0; ! 634: else ! 635: ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | ! 636: SERVICE_ACCEPT_PAUSE_CONTINUE; ! 637: ! 638: // These SERVICE_STATUS members are set from parameters. ! 639: // ! 640: ssStatus.dwCurrentState = dwCurrentState; ! 641: ssStatus.dwWin32ExitCode = dwWin32ExitCode; ! 642: ssStatus.dwCheckPoint = dwCheckPoint; ! 643: ! 644: ssStatus.dwWaitHint = dwWaitHint; ! 645: ! 646: // Report the status of the service to the service control manager. ! 647: // ! 648: if (!(fResult = SetServiceStatus( ! 649: sshStatusHandle, // service reference handle ! 650: &ssStatus))) { // SERVICE_STATUS structure ! 651: ! 652: // If an error occurs, stop the service. ! 653: // ! 654: StopSimpleService("SetServiceStatus"); ! 655: } ! 656: return fResult; ! 657: } ! 658: ! 659: ! 660: ! 661: // The StopSimpleService function can be used by any thread to report an ! 662: // error, or stop the service. ! 663: // ! 664: VOID ! 665: StopSimpleService(LPTSTR lpszMsg) ! 666: { ! 667: CHAR chMsg[256]; ! 668: HANDLE hEventSource; ! 669: LPTSTR lpszStrings[2]; ! 670: ! 671: dwGlobalErr = GetLastError(); ! 672: ! 673: // Use event logging to log the error. ! 674: // ! 675: hEventSource = RegisterEventSource(NULL, ! 676: TEXT("SimpleService")); ! 677: ! 678: sprintf(chMsg, "SimpleService error: %d", dwGlobalErr); ! 679: lpszStrings[0] = chMsg; ! 680: lpszStrings[1] = lpszMsg; ! 681: ! 682: if (hEventSource != NULL) { ! 683: ReportEvent(hEventSource, // handle of event source ! 684: EVENTLOG_ERROR_TYPE, // event type ! 685: 0, // event category ! 686: 0, // event ID ! 687: NULL, // current user's SID ! 688: 2, // strings in lpszStrings ! 689: 0, // no bytes of raw data ! 690: lpszStrings, // array of error strings ! 691: NULL); // no raw data ! 692: ! 693: (VOID) DeregisterEventSource(hEventSource); ! 694: } ! 695: ! 696: // Set a termination event to stop SERVICE MAIN FUNCTION. ! 697: // ! 698: SetEvent(hServDoneEvent); ! 699: } ! 700: ! 701: /****************************************************************************\ ! 702: * ! 703: * FUNCTION: WriteSD_ToA_File ! 704: * ! 705: \****************************************************************************/ ! 706: ! 707: BOOL WriteSD_ToA_File(PSECURITY_DESCRIPTOR psdAbsoluteSD, LPTSTR lpszFileName) ! 708: { ! 709: DWORD dwErrorMode; ! 710: BOOL bStatus; ! 711: ! 712: /**************************************************************************\ ! 713: * ! 714: * SetErrorMode so we don't get the error due to no floppy disk in the floppy ! 715: * drive ! 716: * ! 717: \**************************************************************************/ ! 718: ! 719: dwErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); ! 720: ! 721: /**************************************************************************\ ! 722: * ! 723: * Write SD to file system ! 724: * ! 725: \**************************************************************************/ ! 726: ! 727: bStatus = SetFileSecurity(lpszFileName, ! 728: (SECURITY_INFORMATION)(DACL_SECURITY_INFORMATION), ! 729: psdAbsoluteSD); ! 730: ! 731: /**************************************************************************\ ! 732: * ! 733: * SetErrorMode back to its previous value ! 734: * ! 735: \**************************************************************************/ ! 736: ! 737: SetErrorMode(dwErrorMode); ! 738: ! 739: if (!bStatus) ! 740: { if (ERROR_FILE_NOT_FOUND == GetLastError()) ! 741: { printf("\nAttempted to lock %s, but it was not found",lpszFileName); ! 742: } ! 743: else ! 744: { PERR("SetFileSecurity"); ! 745: return(FALSE); ! 746: } ! 747: } ! 748: ! 749: return(TRUE); ! 750: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.