Annotation of q_a/samples/sd_flppy/floplock.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.