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

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;
1.1.1.2 ! root       66: BOOL                 bGotPowerUsersSid  = FALSE;
1.1       root       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:     *
1.1.1.2 ! root      188:     * Get SID of Power Users, which is not defined on Windows NT Advanced
        !           189:     *   Server machines, so if we fail to get the SID, simply record that
        !           190:     *   fact, and don't try to use the Power Users' SID later
1.1       root      191:     *
                    192:     \************************************************************************/
                    193: 
                    194:     {
                    195:       UCHAR                ucDomainBuf     [SZ_DOMAIN_BUF] = "";
                    196:       UCHAR                ucPSNUBuf       [SZ_PSNU_BUF]   = "";
                    197: 
                    198:       DWORD                dwDomainName   = SZ_DOMAIN_BUF;
                    199: 
                    200:       LPSTR                lpszDomain     = (LPSTR)&ucDomainBuf;
                    201:       PSID_NAME_USE        psnuType       = (PSID_NAME_USE)&ucPSNUBuf;
                    202: 
1.1.1.2 ! root      203:       bGotPowerUsersSid =
        !           204:           LookupAccountName((LPSTR)NULL, /* local name */
1.1       root      205:                             "Power Users",
                    206:                             psidPowerUsers,
                    207:                             &dwSID,
                    208:                             lpszDomain,
                    209:                             &dwDomainName,
1.1.1.2 ! root      210:                             psnuType);
1.1       root      211: 
1.1.1.2 ! root      212:       if(bGotPowerUsersSid)
        !           213:       { if (*psnuType != SidTypeAlias)
        !           214:         { StopSimpleService("LookupAccountName returned the wrong SID type");
        !           215:         }
1.1       root      216:       }
                    217:     }
                    218: 
                    219:     /************************************************************************\
                    220:     *
                    221:     * Initialize new DACL
                    222:     *
                    223:     \************************************************************************/
                    224: 
                    225:     if (!InitializeAcl(pNewDACL,
                    226:                        dwDACL,
                    227:                        ACL_REVISION2))
                    228:     { StopSimpleService("InitializeAcl");
                    229:     }
                    230: 
                    231:     /************************************************************************\
                    232:     *
                    233:     * Allow All access for local Administrators only
                    234:     *
                    235:     \************************************************************************/
                    236: 
                    237:     if (!AddAccessAllowedAce(pNewDACL,
                    238:                              ACL_REVISION2,
                    239:                              FILE_ALL_ACCESS,
                    240:                              psidAdministrators))
                    241:     { StopSimpleService("AddAccessAllowedAce");
                    242:     }
                    243: 
                    244:     /************************************************************************\
                    245:     *
                    246:     * If we unlock the floppies when the service stops, then for the sake of
                    247:     *   consistency, we have to also allow Power Users on the Admin-only DACL,
                    248:     *   since Power Users can stop services.  It would be inconsistent to try
                    249:     *   to lock Power Users away from their floppies if Power Users could get
                    250:     *   to the floppies simply by stopping the service
                    251:     *
                    252:     * It's still OK to use the same DACL for the pipe as for the floppies,
                    253:     *   that is, it's OK to let Power Users on the DACL for the pipe too.  The
                    254:     *   reason is that it is not generally (and certainly not by default) the
                    255:     *   case that an account is a member of Power Users on more than their own
                    256:     *   machines.  So, putting Power Users on the pipe let's Power Users admin
                    257:     *   the floppies via the pipe only on the machines on which they are
                    258:     *   actually Power Users, and again, on those machines they can stop the
                    259:     *   floppy-locking service as well
                    260:     *
                    261:     \************************************************************************/
                    262: 
                    263:     #define UNLOCK_AT_SERVICE_STOP (0==0)
1.1.1.2 ! root      264:     if     (UNLOCK_AT_SERVICE_STOP && bGotPowerUsersSid)
1.1       root      265:     { if (!AddAccessAllowedAce(pNewDACL,
                    266:                                ACL_REVISION2,
                    267:                                FILE_ALL_ACCESS,
                    268:                                psidPowerUsers))
                    269:       { StopSimpleService("AddAccessAllowedAce");
                    270:       }
                    271:     }
                    272: 
                    273:     /************************************************************************\
                    274:     *
                    275:     * Build SD in absolute format - first the Admins-only then the Everyone SD
                    276:     *
                    277:     \************************************************************************/
                    278: 
                    279:     if (!InitializeSecurityDescriptor(psdAbsoluteSD,
                    280:                                       SECURITY_DESCRIPTOR_REVISION))
                    281:     { StopSimpleService("InitializeSecurityDescriptor");
                    282:     }
                    283: 
                    284:     if (!InitializeSecurityDescriptor(psdEveryoneSD,
                    285:                                       SECURITY_DESCRIPTOR_REVISION))
                    286:     { StopSimpleService("InitializeSecurityDescriptor");
                    287:     }
                    288: 
                    289:     /************************************************************************\
                    290:     *
                    291:     * Set DACL into SD - first the Admins-only then the Everyone SD
                    292:     *
                    293:     \************************************************************************/
                    294: 
                    295:     if (!SetSecurityDescriptorDacl(psdAbsoluteSD,
                    296:                                    TRUE,      // fDaclPresent flag
                    297:                                    pNewDACL,
                    298:                                    FALSE))    // not a default DACL
                    299:     { StopSimpleService("SetSecurityDescriptorDacl");
                    300:     }
                    301: 
                    302:     if (!SetSecurityDescriptorDacl(psdEveryoneSD,
                    303:                                    TRUE,      // fDaclPresent flag
                    304:                                    (PACL)NULL,
                    305:                                    FALSE))    // not a default DACL
                    306:     { StopSimpleService("SetSecurityDescriptorDacl");
                    307:     }
                    308: 
                    309:     /************************************************************************\
                    310:     *
                    311:     * Check to see that SD is valid before attempting to write it to the file
                    312:     *
                    313:     \************************************************************************/
                    314: 
                    315:     if (!IsValidSecurityDescriptor(psdAbsoluteSD))
                    316:     { StopSimpleService("IsValidSecurityDescriptor");
                    317:     }
                    318: 
                    319:     sa.nLength = sizeof(sa);
                    320:     sa.lpSecurityDescriptor = psdAbsoluteSD;
                    321:     sa.bInheritHandle = TRUE;  // why not... we spawn no processes
                    322: 
                    323:     // open our named pipe...
                    324:     //
                    325:     pipeHandle = CreateNamedPipe(
                    326:                     "\\\\.\\pipe\\sd_flppy",  // name of pipe
                    327:                     PIPE_ACCESS_DUPLEX,     // pipe open mode
                    328:                     PIPE_TYPE_MESSAGE |
                    329:                     PIPE_READMODE_MESSAGE |
                    330:                     PIPE_WAIT,              // pipe IO type
                    331:                     1,                      // number of instances
                    332:                     0,                      // size of outbuf (0 == allocate as necessary)
                    333:                     0,                      // size of inbuf
                    334:                     1000,                   // default time-out value
                    335:                     &sa);                   // security attributes
                    336: 
                    337:     if (!pipeHandle) {
                    338:         StopSimpleService("CreateNamedPipe");
                    339:         return;
                    340:     }
                    341: 
                    342:     // Set the same DACL onto the floppies
                    343:     //
                    344: 
                    345:     /************************************************************************\
                    346:     *
                    347:     * Write SD to file system - first for A: then B:
                    348:     *
                    349:     \************************************************************************/
                    350: 
                    351:     if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\A:"))
                    352:     { StopSimpleService("Write of DACL to A: failed");
                    353:     }
                    354: 
                    355:     if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\B:"))
                    356:     { StopSimpleService("Write of DACL to B: failed");
                    357:     }
                    358: 
                    359:     bFloppiesAreLocked = TRUE;
                    360: 
                    361:     /************************************************************************\
                    362:     *
                    363:     * Works for CDROM drives as well - commented out as this samples is floppy
                    364:     *   only
                    365:     *
                    366:     \************************************************************************/
                    367:   /*
                    368:     if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\E:"))
                    369:     { StopSimpleService("Write of DACL to E: failed");
                    370:     }
                    371:   */
                    372:     /************************************************************************\
                    373:     *
                    374:     * Works for COM ports as well - commented out as this samples is floppy only
                    375:     *
                    376:     \************************************************************************/
                    377:   /*
                    378:     if (!WriteSD_ToA_File(psdAbsoluteSD,"COM1:"))
                    379:     { StopSimpleService("Write of DACL to COM1: failed");
                    380:     }
                    381:   */
                    382: 
                    383:     // start the thread that performs the work of the service.
                    384:     //
                    385:     threadHandle = CreateThread(
                    386:                     NULL,       // security attributes
                    387:                     0,          // stack size (0 means inherit parent's stack size)
                    388:                     (LPTHREAD_START_ROUTINE)worker_thread,
                    389:                     NULL,       // argument to thread
                    390:                     0,          // thread creation flags
                    391:                     &TID);      // pointer to thread ID
                    392: 
                    393:     if (!threadHandle)
                    394:         goto cleanup;
                    395: 
                    396:     // report the status to the service control manager.
                    397:     //
                    398:     if (!ReportStatusToSCMgr(
                    399:         SERVICE_RUNNING, // service state
                    400:         NO_ERROR,        // exit code
                    401:         0,               // checkpoint
                    402:         0))              // wait hint
                    403:         goto cleanup;
                    404: 
                    405:     // wait indefinitely until hServDoneEvent is signaled.
                    406:     //
                    407:     dwWait = WaitForSingleObject(
                    408:         hServDoneEvent,  // event object
                    409:         INFINITE);       // wait indefinitely
                    410: 
                    411: cleanup:
                    412: 
                    413:     if (hServDoneEvent != NULL)
                    414:         CloseHandle(hServDoneEvent);
                    415: 
                    416: 
                    417:     // try to report the stopped status to the service control manager.
                    418:     //
                    419:     if (sshStatusHandle != 0)
                    420:         (VOID)ReportStatusToSCMgr(
                    421:                             SERVICE_STOPPED,
                    422:                             dwGlobalErr,
                    423:                             0,
                    424:                             0);
                    425: 
                    426:     // When SERVICE MAIN FUNCTION returns in a single service
                    427:     // process, the StartServiceCtrlDispatcher function in
                    428:     // the main thread returns, terminating the process.
                    429:     //
                    430:     return;
                    431: }
                    432: 
                    433: 
                    434: 
                    435: //  service_ctrl() --
                    436: //      this function is called by the Service Controller whenever
                    437: //      someone calls ControlService in reference to our service.
                    438: //
                    439: VOID
                    440: service_ctrl(DWORD dwCtrlCode)
                    441: {
                    442:     DWORD  dwState = SERVICE_RUNNING;
                    443: 
                    444:     // Handle the requested control code.
                    445:     //
                    446:     switch(dwCtrlCode) {
                    447: 
                    448:         // Pause the service if it is running.
                    449:         //
                    450:         case SERVICE_CONTROL_PAUSE:
                    451: 
                    452:             if (ssStatus.dwCurrentState == SERVICE_RUNNING) {
                    453:                 SuspendThread(threadHandle);
                    454:                 dwState = SERVICE_PAUSED;
                    455:             }
                    456:             break;
                    457: 
                    458:         // Resume the paused service.
                    459:         //
                    460:         case SERVICE_CONTROL_CONTINUE:
                    461: 
                    462:             if (ssStatus.dwCurrentState == SERVICE_PAUSED) {
                    463:                 ResumeThread(threadHandle);
                    464:                 dwState = SERVICE_RUNNING;
                    465:             }
                    466:             break;
                    467: 
                    468:         // Stop the service.
                    469:         //
                    470:         case SERVICE_CONTROL_STOP:
                    471: 
                    472:             dwState = SERVICE_STOP_PENDING;
                    473: 
                    474:             // Report the status, specifying the checkpoint and waithint,
                    475:             //  before setting the termination event.
                    476:             //
                    477:             ReportStatusToSCMgr(
                    478:                     SERVICE_STOP_PENDING, // current state
                    479:                     NO_ERROR,             // exit code
                    480:                     1,                    // checkpoint
                    481:                     3000);                // waithint
                    482: 
                    483:             if     (UNLOCK_AT_SERVICE_STOP)
                    484:             { if (!WriteSD_ToA_File(psdEveryoneSD,"\\\\.\\A:"))
                    485:               { StopSimpleService("Unlock of A: failed, see log file");
                    486:               }
                    487:               if (!WriteSD_ToA_File(psdEveryoneSD,"\\\\.\\B:"))
                    488:               { StopSimpleService("Unlock of B: failed, see log file");
                    489:               }
                    490: 
                    491:               bFloppiesAreLocked = FALSE;
                    492:             }
                    493: 
                    494:             SetEvent(hServDoneEvent);
                    495:             return;
                    496: 
                    497:         // Update the service status.
                    498:         //
                    499:         case SERVICE_CONTROL_INTERROGATE:
                    500:             break;
                    501: 
                    502:         // invalid control code
                    503:         //
                    504:         default:
                    505:             break;
                    506: 
                    507:     }
                    508: 
                    509:     // send a status response.
                    510:     //
                    511:     ReportStatusToSCMgr(dwState, NO_ERROR, 0, 0);
                    512: }
                    513: 
                    514: 
                    515: 
                    516: //  worker_thread() --
                    517: //      this function does the actual nuts and bolts work that
                    518: //      the service requires.  It will also Pause or Stop when
                    519: //      asked by the service_ctrl function.
                    520: //
                    521: VOID
                    522: worker_thread(VOID *notUsed)
                    523: {
                    524:     char                 inbuf[180];
                    525:     char                 outbuf[180];
                    526:     BOOL                 ret;
                    527:     DWORD                bytesRead;
                    528:     DWORD                bytesWritten;
                    529:     DWORD                dwLen;
                    530: 
                    531:     // okay, our pipe has been created, let's enter the simple
                    532:     //  processing loop...
                    533:     //
                    534:     while (1) {
                    535: 
                    536:         // wait for a connection...
                    537:         //
                    538:         ConnectNamedPipe(pipeHandle, NULL);
                    539: 
                    540:         // grab whatever's coming through the pipe...
                    541:         //
                    542:         ret = ReadFile(
                    543:                     pipeHandle,     // file to read from
                    544:                     inbuf,          // address of input buffer
                    545:                     sizeof(inbuf),  // number of bytes to read
                    546:                     &bytesRead,     // number of bytes read
                    547:                     NULL);          // overlapped stuff, not needed
                    548: 
                    549:         if (!ret)
                    550:             // pipe's broken... go back and reconnect
                    551:             //
                    552:             continue;
                    553: 
                    554:         switch (inbuf[0])
                    555:         { case 'U':
                    556:             dwLen = sprintf(outbuf,"Floppies were unlocked");
                    557: 
                    558:             if (!WriteSD_ToA_File(psdEveryoneSD,"\\\\.\\A:"))
                    559:             { dwLen += sprintf(outbuf+dwLen,", unlock of A: failed, see log file");
                    560:             }
                    561:             if (!WriteSD_ToA_File(psdEveryoneSD,"\\\\.\\B:"))
                    562:             { dwLen += sprintf(outbuf+dwLen,", unlock of B: failed, see log file");
                    563:             }
                    564: 
                    565:             bFloppiesAreLocked = FALSE;
                    566:             break;
                    567: 
                    568:           case 'L':
                    569:             dwLen = sprintf(outbuf,"Floppies were locked");
                    570: 
                    571:             if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\A:"))
                    572:             { dwLen += sprintf(outbuf+dwLen,", lock of A: failed, see log file");
                    573:             }
                    574:             if (!WriteSD_ToA_File(psdAbsoluteSD,"\\\\.\\B:"))
                    575:             { dwLen += sprintf(outbuf+dwLen,", lock of B: failed, see log file");
                    576:             }
                    577: 
                    578:             bFloppiesAreLocked = TRUE;
                    579:             break;
                    580: 
                    581:           case 'Q':
                    582:             if (bFloppiesAreLocked)
                    583:             { sprintf(outbuf,"Floppy status is: Locked");
                    584:             }
                    585:             else
                    586:             { sprintf(outbuf,"Floppy status is: Unlocked");
                    587:             }
                    588:             break;
                    589: 
                    590:           default :
                    591:             sprintf(outbuf,"Bad operation passed in");
                    592:         }
                    593: 
                    594:         // send it back out...
                    595:         //
                    596:         ret = WriteFile(
                    597:                     pipeHandle,     // file to write to
                    598:                     outbuf,         // address of output buffer
                    599:                     sizeof(outbuf), // number of bytes to write
                    600:                     &bytesWritten,  // number of bytes written
                    601:                     NULL);          // overlapped stuff, not needed
                    602: 
                    603:         if (!ret)
                    604:             // pipe's broken... go back and reconnect
                    605:             //
                    606:             continue;
                    607: 
                    608:         // drop the connection...
                    609:         //
                    610:         DisconnectNamedPipe(pipeHandle);
                    611:     }
                    612: }
                    613: 
                    614: 
                    615: 
                    616: // utility functions...
                    617: 
                    618: 
                    619: 
                    620: // ReportStatusToSCMgr() --
                    621: //      This function is called by the ServMainFunc() and
                    622: //      ServCtrlHandler() functions to update the service's status
                    623: //      to the service control manager.
                    624: //
                    625: BOOL
                    626: ReportStatusToSCMgr(DWORD dwCurrentState,
                    627:                     DWORD dwWin32ExitCode,
                    628:                     DWORD dwCheckPoint,
                    629:                     DWORD dwWaitHint)
                    630: {
                    631:     BOOL fResult;
                    632: 
                    633:     // Disable control requests until the service is started.
                    634:     //
                    635:     if (dwCurrentState == SERVICE_START_PENDING)
                    636:         ssStatus.dwControlsAccepted = 0;
                    637:     else
                    638:         ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
                    639:             SERVICE_ACCEPT_PAUSE_CONTINUE;
                    640: 
                    641:     // These SERVICE_STATUS members are set from parameters.
                    642:     //
                    643:     ssStatus.dwCurrentState = dwCurrentState;
                    644:     ssStatus.dwWin32ExitCode = dwWin32ExitCode;
                    645:     ssStatus.dwCheckPoint = dwCheckPoint;
                    646: 
                    647:     ssStatus.dwWaitHint = dwWaitHint;
                    648: 
                    649:     // Report the status of the service to the service control manager.
                    650:     //
                    651:     if (!(fResult = SetServiceStatus(
                    652:                 sshStatusHandle,    // service reference handle
                    653:                 &ssStatus))) {      // SERVICE_STATUS structure
                    654: 
                    655:         // If an error occurs, stop the service.
                    656:         //
                    657:         StopSimpleService("SetServiceStatus");
                    658:     }
                    659:     return fResult;
                    660: }
                    661: 
                    662: 
                    663: 
                    664: // The StopSimpleService function can be used by any thread to report an
                    665: //  error, or stop the service.
                    666: //
                    667: VOID
                    668: StopSimpleService(LPTSTR lpszMsg)
                    669: {
                    670:     CHAR    chMsg[256];
                    671:     HANDLE  hEventSource;
                    672:     LPTSTR  lpszStrings[2];
                    673: 
                    674:     dwGlobalErr = GetLastError();
                    675: 
                    676:     // Use event logging to log the error.
                    677:     //
                    678:     hEventSource = RegisterEventSource(NULL,
                    679:                             TEXT("SimpleService"));
                    680: 
                    681:     sprintf(chMsg, "SimpleService error: %d", dwGlobalErr);
                    682:     lpszStrings[0] = chMsg;
                    683:     lpszStrings[1] = lpszMsg;
                    684: 
                    685:     if (hEventSource != NULL) {
                    686:         ReportEvent(hEventSource, // handle of event source
                    687:             EVENTLOG_ERROR_TYPE,  // event type
                    688:             0,                    // event category
                    689:             0,                    // event ID
                    690:             NULL,                 // current user's SID
                    691:             2,                    // strings in lpszStrings
                    692:             0,                    // no bytes of raw data
                    693:             lpszStrings,          // array of error strings
                    694:             NULL);                // no raw data
                    695: 
                    696:         (VOID) DeregisterEventSource(hEventSource);
                    697:     }
                    698: 
                    699:     // Set a termination event to stop SERVICE MAIN FUNCTION.
                    700:     //
                    701:     SetEvent(hServDoneEvent);
                    702: }
                    703: 
                    704: /****************************************************************************\
                    705: *
                    706: * FUNCTION: WriteSD_ToA_File
                    707: *
                    708: \****************************************************************************/
                    709: 
                    710: BOOL WriteSD_ToA_File(PSECURITY_DESCRIPTOR psdAbsoluteSD, LPTSTR lpszFileName)
                    711: {
                    712:   DWORD dwErrorMode;
                    713:   BOOL  bStatus;
                    714: 
                    715:   /**************************************************************************\
                    716:   *
                    717:   * SetErrorMode so we don't get the error due to no floppy disk in the floppy
                    718:   *   drive
                    719:   *
                    720:   \**************************************************************************/
                    721: 
                    722:   dwErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
                    723: 
                    724:   /**************************************************************************\
                    725:   *
                    726:   * Write SD to file system
                    727:   *
                    728:   \**************************************************************************/
                    729: 
                    730:   bStatus = SetFileSecurity(lpszFileName,
                    731:                             (SECURITY_INFORMATION)(DACL_SECURITY_INFORMATION),
                    732:                             psdAbsoluteSD);
                    733: 
                    734:   /**************************************************************************\
                    735:   *
                    736:   * SetErrorMode back to its previous value
                    737:   *
                    738:   \**************************************************************************/
                    739: 
                    740:   SetErrorMode(dwErrorMode);
                    741: 
                    742:   if (!bStatus)
                    743:   { if (ERROR_FILE_NOT_FOUND == GetLastError())
                    744:     { printf("\nAttempted to lock %s, but it was not found",lpszFileName);
                    745:     }
                    746:     else
                    747:     { PERR("SetFileSecurity");
                    748:       return(FALSE);
                    749:     }
                    750:   }
                    751: 
                    752:   return(TRUE);
                    753: }

unix.superglobalmegacorp.com

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