Beispiel #1
0
/***********************************************************************************************************************************
Remote command
***********************************************************************************************************************************/
void
cmdRemote(int handleRead, int handleWrite)
{
    FUNCTION_LOG_VOID(logLevelDebug);

    MEM_CONTEXT_TEMP_BEGIN()
    {
        String *name = strNewFmt(PROTOCOL_SERVICE_REMOTE "-%u", cfgOptionUInt(cfgOptProcess));
        IoRead *read = ioHandleReadNew(name, handleRead, (TimeMSec)(cfgOptionDbl(cfgOptProtocolTimeout) * 1000));
        ioReadOpen(read);
        IoWrite *write = ioHandleWriteNew(name, handleWrite);
        ioWriteOpen(write);

        ProtocolServer *server = protocolServerNew(name, PROTOCOL_SERVICE_REMOTE_STR, read, write);
        protocolServerHandlerAdd(server, storageRemoteProtocol);
        protocolServerHandlerAdd(server, configProtocol);

        // Acquire a lock if this command needs one.  We'll use the noop that is always sent from the client right after the
        // handshake to return an error.
        volatile bool success = false;

        TRY_BEGIN()
        {
            // Read the command.  No need to parse it since we know this is the first noop.
            ioReadLine(read);

            // Only try the lock if this is process 0, i.e. the remote started from the main process
            if (cfgOptionUInt(cfgOptProcess) == 0)
            {
                ConfigCommand commandId = cfgCommandId(strPtr(cfgOptionStr(cfgOptCommand)));

                // Acquire a lock if this command requires a lock
                if (cfgLockRemoteRequired(commandId))
                    lockAcquire(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgLockRemoteType(commandId), 0, true);
            }

            protocolServerResponse(server, NULL);
            success = true;
        }
        CATCH_ANY()
        {
            protocolServerError(server, errorCode(), STR(errorMessage()), STR(errorStackTrace()));
        }
        TRY_END();

        // If not successful we'll just exit
        if (success)
            protocolServerProcess(server);
    }
    MEM_CONTEXT_TEMP_END();

    FUNCTION_LOG_RETURN_VOID();
}
Beispiel #2
0
/***********************************************************************************************************************************
Compare log to a regexp

After the comparison the log is cleared so the next result can be compared.
***********************************************************************************************************************************/
void
harnessLogResultRegExp(const char *expression)
{
    FUNCTION_HARNESS_BEGIN();
        FUNCTION_HARNESS_PARAM(STRINGZ, expression);

        FUNCTION_HARNESS_ASSERT(expression != NULL);
    FUNCTION_HARNESS_END();

    regex_t regExp;

    TRY_BEGIN()
    {
        harnessLogLoad(logFile);

        // Compile the regexp and process errors
        int result = 0;

        if ((result = regcomp(&regExp, expression, REG_NOSUB | REG_EXTENDED)) != 0)
        {
            char buffer[4096];
            regerror(result, NULL, buffer, sizeof(buffer));
            THROW(FormatError, buffer);
        }

        // Do the match
        if (regexec(&regExp, harnessLogBuffer, 0, NULL, 0) != 0)
            THROW_FMT(AssertError, "\n\nexpected log regexp:\n\n%s\n\nbut actual log was:\n\n%s\n\n", expression, harnessLogBuffer);

        close(logHandleFile);
        logHandleFile = harnessLogOpen(logFile, O_WRONLY | O_CREAT | O_TRUNC, 0640);
    }
    FINALLY()
    {
        regfree(&regExp);
    }
    TRY_END();

    FUNCTION_HARNESS_RESULT_VOID();
}
Beispiel #3
0
/***********************************************************************************************************************************
Test Run
***********************************************************************************************************************************/
void
testRun(void)
{
    FUNCTION_HARNESS_VOID();

    // *****************************************************************************************************************************
    if (testBegin("stackTraceFmt()"))
    {
        char buffer[8];

        TEST_RESULT_INT(stackTraceFmt(buffer, 8, 0, "%s", "1234567"), 7, "fill buffer");
        TEST_RESULT_STR(buffer, "1234567", "    check buffer");
        TEST_RESULT_INT(stackTraceFmt(buffer, 8, 7, "%s", "1234567"), 7, "try to fill buffer - at end");
        TEST_RESULT_STR(buffer, "1234567", "    check buffer is unmodified");
        TEST_RESULT_INT(stackTraceFmt(buffer, 8, 8, "%s", "1234567"), 7, "try to fill buffer - past end");
        TEST_RESULT_STR(buffer, "1234567", "    check buffer is unmodified");
    }

    // *****************************************************************************************************************************
    if (testBegin("stackTraceInit() and stackTraceError()"))
    {
#ifdef WITH_BACKTRACE
        stackTraceInit(BOGUS_STR);

        // This time does nothing
        stackTraceInit(BOGUS_STR);

        // This will call the error routine since we passed a bogus exe
        assert(stackTracePush("file1.c", "function1", logLevelDebug) == logLevelDebug);
        stackTracePop("file1.c", "function1");

        backTraceState = NULL;
#endif
    }

    // *****************************************************************************************************************************
    if (testBegin("stackTraceTestStart(), stackTraceTestStop(), and stackTraceTest()"))
    {
#ifndef NDEBUG
        assert(stackTraceTest());

        stackTraceTestStop();
        assert(!stackTraceTest());

        stackTraceTestStart();
        assert(stackTraceTest());
#endif
    }

    // *****************************************************************************************************************************
    if (testBegin("stackTracePush(), stackTracePop(), and stackTraceClean()"))
    {
        char buffer[4096];

#ifdef WITH_BACKTRACE
        stackTraceInit(testExe());
#endif

        TEST_ERROR(stackTracePop("file1", "function1", false), AssertError, "assertion 'stackSize > 0' failed");

        assert(stackTracePush("file1", "function1", logLevelDebug) == logLevelDebug);
        assert(stackSize == 1);

        TEST_ERROR(
            stackTracePop("file2", "function2", false), AssertError,
            "popping file2:function2 but expected file1:function1");

        assert(stackTracePush("file1", "function1", logLevelDebug) == logLevelDebug);

        TEST_ERROR(
            stackTracePop("file1", "function2", false), AssertError,
            "popping file1:function2 but expected file1:function1");

        TRY_BEGIN()
        {
            assert(stackTracePush("file1.c", "function1", logLevelDebug) == logLevelDebug);
            stackTraceParamLog();
            assert(strcmp(stackTraceParam(), "void") == 0);

            stackTraceToZ(buffer, sizeof(buffer), "file1.c", "function2", 99);

#ifdef WITH_BACKTRACE
            TEST_RESULT_STR(
                buffer,
                "file1:function2:99:(test build required for parameters)\n"
                "    ... function(s) ommitted ...\n"
                "file1:function1:0:(void)",
                "    check stack trace");
#else
            TEST_RESULT_STR(
                buffer,
                "file1:function2:99:(test build required for parameters)\n"
                "    ... function(s) ommitted ...\n"
                "file1:function1:(void)",
                "    check stack trace");
#endif

            assert(stackTracePush("file1.c", "function2", logLevelTrace) == logLevelTrace);
            stackTrace[stackSize - 2].fileLine = 7777;
            assert(strcmp(stackTraceParam(), "trace log level required for parameters") == 0);
            stackTrace[stackSize - 1].functionLogLevel = logLevelDebug;

            TRY_BEGIN()
            {
                // Function with one param
                assert(stackTracePush("file2.c", "function2", logLevelDebug) == logLevelDebug);
                stackTrace[stackSize - 2].fileLine = 7777;

                stackTraceParamAdd((size_t)snprintf(stackTraceParamBuffer("param1"), STACK_TRACE_PARAM_MAX, "value1"));
                stackTraceParamLog();
                assert(strcmp(stackTraceParam(), "param1: value1") == 0);

                // Function with multiple params
                assert(stackTracePush("file3.c", "function3", logLevelTrace) == logLevelTrace);
                stackTrace[stackSize - 2].fileLine = 7777;

                stackTraceParamLog();
                stackTraceParamAdd((size_t)snprintf(stackTraceParamBuffer("param1"), STACK_TRACE_PARAM_MAX, "value1"));
                stackTraceParamAdd((size_t)snprintf(stackTraceParamBuffer("param2"), STACK_TRACE_PARAM_MAX, "value2"));
                assert(strcmp(stackTraceParam(), "param1: value1, param2: value2") == 0);

                // Calculate exactly where the buffer will overflow (4 is for the separators)
                size_t bufferOverflow =
                    sizeof(functionParamBuffer) - (STACK_TRACE_PARAM_MAX * 2) - strlen("param1") - 4 -
                    (size_t)(stackTrace[stackSize - 1].param - functionParamBuffer);

                // Munge the previous previous param in the stack so that the next one will just barely fit
                stackTrace[stackSize - 1].paramSize = bufferOverflow - 1;

                assert(stackTracePush("file4.c", "function4", logLevelDebug) == logLevelTrace);
                stackTrace[stackSize - 2].fileLine = 7777;
                stackTraceParamLog();
                assert(stackSize == 5);

                // This param will fit exactly
                stackTraceParamAdd((size_t)snprintf(stackTraceParamBuffer("param1"), STACK_TRACE_PARAM_MAX, "value1"));
                assert(strcmp(stackTraceParam(), "param1: value1") == 0);

                // But when we increment the param pointer by one there will be overflow
                stackTrace[stackSize - 1].param += 1;
                stackTrace[stackSize - 1].paramSize = 0;
                stackTraceParamAdd((size_t)snprintf(stackTraceParamBuffer("param1"), STACK_TRACE_PARAM_MAX, "value1"));
                assert(strcmp(stackTraceParam(), "buffer full - parameters not available") == 0);

                stackTraceToZ(buffer, sizeof(buffer), "file4.c", "function4", 99);

#ifdef WITH_BACKTRACE
                TEST_RESULT_STR(
                    buffer,
                    "file4:function4:99:(buffer full - parameters not available)\n"
                    "file3:function3:7777:(param1: value1, param2: value2)\n"
                    "file2:function2:7777:(param1: value1)\n"
                    "file1:function2:7777:(debug log level required for parameters)\n"
                    "file1:function1:7777:(void)",
                    "stack trace");
#else
                TEST_RESULT_STR(
                    buffer,
                    "file4:function4:99:(buffer full - parameters not available)\n"
                    "file3:function3:(param1: value1, param2: value2)\n"
                    "file2:function2:(param1: value1)\n"
                    "file1:function2:(debug log level required for parameters)\n"
                    "file1:function1:(void)",
                    "stack trace");
#endif

                stackTracePop("file4.c", "function4", false);
                assert(stackSize == 4);

                // Check that stackTracePop() works with test tracing
                stackTracePush("file_test.c", "function_test", logLevelDebug);
                stackTracePop("file_test.c", "function_test", true);

                // Check that stackTracePop() does nothing when test tracing is disabled
                stackTraceTestStop();
                stackTracePop("bogus.c", "bogus", true);
                stackTraceTestStart();

                THROW(ConfigError, "test");
            }
            CATCH(ConfigError)
            {
                // Ignore the error since we are just testing stack cleaup
            }
            TRY_END();

            assert(stackSize == 2);
            THROW(ConfigError, "test");
        }
        CATCH(ConfigError)
        {
            // Ignore the error since we are just testing stack cleaup
        }
        TRY_END();

        assert(stackSize == 0);
    }
Beispiel #4
0
/***********************************************************************************************************************************
Do cleanup and return result code
***********************************************************************************************************************************/
int
exitSafe(int result, bool error, SignalType signalType)
{
    FUNCTION_LOG_BEGIN(logLevelDebug);
        FUNCTION_LOG_PARAM(INT, result);
        FUNCTION_LOG_PARAM(BOOL, error);
        FUNCTION_LOG_PARAM(ENUM, signalType);
    FUNCTION_LOG_END();

    // Report error if one was thrown
    if (error)
    {
        // Don't log the error if it has already been logged by Perl
#ifdef HAVE_LIBPERL
        if (strcmp(errorMessage(), PERL_EMBED_ERROR) != 0)
        {
#endif
            LogLevel logLevel = errorCode() == errorTypeCode(&AssertError) ? logLevelAssert : logLevelError;

            // Assert errors always output a stack trace
            if (logLevel == logLevelAssert)
                LOG(logLevel, errorCode(), "%s\nSTACK TRACE:\n%s", errorMessage(), errorStackTrace());
            else
            {
                // Log just the error to non-debug levels
                LOG_INTERNAL(logLevel, LOG_LEVEL_MIN, logLevelDetail, 0, errorCode(), errorMessage());

                // Log the stack trace debug levels
                if (logAny(logLevelDebug))
                {
                    LOG_INTERNAL(
                        logLevel, logLevelDebug, LOG_LEVEL_MAX, 0, errorCode(), "%s\nSTACK TRACE:\n%s", errorMessage(),
                        errorStackTrace());
                }
            }
#ifdef HAVE_LIBPERL
        }
#endif

        result = errorCode();
    }

    // Free protocol objects but ignore errors
    TRY_BEGIN()
    {
        protocolFree();
    }
    TRY_END();

    // Free Perl but ignore errors
#ifdef HAVE_LIBPERL
    TRY_BEGIN()
    {
        perlFree(result);
    }
    TRY_END();
#endif

    // Log command end if a command is set
    if (cfgCommand() != cfgCmdNone)
    {
        String *errorMessage = NULL;

        // On error generate an error message
        if (result != 0)
        {
            // On process terminate
            if (result == errorTypeCode(&TermError))
            {
                errorMessage = strNew("terminated on signal ");

                // Terminate from a child
                if (signalType == signalTypeNone)
                    strCat(errorMessage, "from child process");
                // Else terminated directly
                else
                    strCatFmt(errorMessage, "[SIG%s]", exitSignalName(signalType));
            }
            // Standard error exit message
            else if (error)
                errorMessage = strNewFmt("aborted with exception [%03d]", result);
        }

        cmdEnd(result, errorMessage);
    }

    // Release any locks but ignore errors
    TRY_BEGIN()
    {
        lockRelease(false);
    }
    TRY_END();

    // Return result - caller should immediate pass this result to exit()
    FUNCTION_LOG_RETURN(INT, result);
}
Beispiel #5
0
INT WSAAPI
WSCInstallNameSpace (
    IN  LPWSTR  lpszIdentifier,
    IN  LPWSTR  lpszPathName,
    IN  DWORD   dwNameSpace,
    IN  DWORD   dwVersion,
    IN  LPGUID  lpProviderId
    )
/*++

Routine Description:

    WSCInstallNameSpace() is used to install a name space provider. For
    providers that are able to support multiple names spaces, this function
    must be called once for every name space supported, and a unique provider
    ID must be supplied each time.

Arguments:

    lpszIdentifier - Display string for the provider.

    lpszPathname - Points to a path to the providers DLL image which
                   follows  the usual rules for path resolution. This path may
                   contain embedded environment strings (such as
                   %SystemRoot%). Such environment strings are expanded
                   whenever the WinSock 2 DLL needs to subsequently load
                   theprovider DLL on behalf of an application. After any
                   embedded environment strings are expanded, the WinSock 2 DLL
                   passes the resulting string into the LoadLibrary() function
                   to load the provider into memory.

    dwNameSpace - Specifies the name space supported by this provider.

    dwVersion - Specifies the version number of the provider.

    bStoresAllServiceClassInfo - Specifies that this provider supports the
                                 storage  of service class schema information
                                 for all service classes across all namespaces.
                                 The Winsock DLL will then use this provider to
                                 get all of its classinfo information rather
                                 than asking each individual provider.

    lpProviderId - A unique identifier for this provider.  This GUID should be
                   generated by UUIDGEN.EXE.

Return Value:

    The function should return NO_ERROR (0) if the routine succeeds.  It should
    return SOCKET_ERROR (-1) if the routine fails and it must set the
    appropriate error code using SetLastError().
--*/
{
    INT             ReturnCode;
    PNSCATALOG      Catalog =NULL;
    PNSCATALOGENTRY Item =NULL;
    HKEY            registry_root;
    BOOL            lock_owned = FALSE;

    registry_root = OpenWinSockRegistryRoot();
    if (NULL == registry_root) {
        DEBUGF(
            DBG_ERR,
            ("Opening registry root\n"));
        SetLastError(WSASYSCALLFAILURE);
        return(SOCKET_ERROR);
    }

    //
    // Check the current protocol catalog key. If it doesn't match
    // the expected value, blow away the old key and update the
    // stored value.
    //

    ValidateCurrentCatalogName(
        registry_root,
        WINSOCK_CURRENT_NAMESPACE_CATALOG_NAME,
        NSCATALOG::GetCurrentCatalogName()
        );

    TRY_START(guard_memalloc){
        GUID_MATCH_CONTEXT context;


        Catalog = new NSCATALOG;
        if (NULL == Catalog){
            ReturnCode = WSA_NOT_ENOUGH_MEMORY;
            TRY_THROW(guard_memalloc);
        } //item

        Item = new NSCATALOGENTRY;
        if (NULL == Item){
            ReturnCode = WSA_NOT_ENOUGH_MEMORY;
            TRY_THROW(guard_memalloc);
        } //if


        __try {
            context.ProviderId = *lpProviderId;
            ReturnCode = Item->InitializeFromValues(
                lpszPathName,
                lpszIdentifier,
                lpProviderId,
                dwNameSpace,
                dwVersion
                );
        }
        __except (WS2_EXCEPTION_FILTER()) {
            ReturnCode = WSAEFAULT;
            TRY_THROW(guard_memalloc);
        }

        if (ERROR_SUCCESS != ReturnCode){
            TRY_THROW(guard_memalloc);
        } //if

        ReturnCode = Catalog->InitializeFromRegistry(
            registry_root,  // ParentKey
            NULL            // ChangeEvent
            );

        if (ERROR_SUCCESS != ReturnCode){
            TRY_THROW(guard_memalloc);
        } //if

        context.CatalogItem = NULL;
        Catalog->EnumerateCatalogItems(
            GuidMatcher,
            &context
            );

        if (context.CatalogItem != NULL){
            ReturnCode = WSAEINVAL;
            TRY_THROW(guard_memalloc);
        } //if

        Catalog->AppendCatalogItem(
            Item
            );
        Item = NULL;  // item deletion is now covered by catalog

        ReturnCode = Catalog->WriteToRegistry();
        if (ReturnCode!=ERROR_SUCCESS) {
            TRY_THROW (guard_memalloc);
        }
        delete Catalog;

    } TRY_CATCH(guard_memalloc){
        assert (ReturnCode!=ERROR_SUCCESS);

        if (Item){
            Item->Dereference ();
        } //if

        if (Catalog){
            delete Catalog;
        } //if

    } TRY_END(guard_memalloc);


    CloseWinSockRegistryRoot(registry_root);

    if (ReturnCode == ERROR_SUCCESS) {
        HANDLE hHelper;

        //
        // Alert all interested apps of change via the notification method
        //


        if (WahOpenNotificationHandleHelper( &hHelper )==ERROR_SUCCESS) {
            WahNotifyAllProcesses( hHelper );
            WahCloseNotificationHandleHelper( hHelper );
        }
        else {
            // This is non-fatal and catalog was updated anyway
        }

        return ERROR_SUCCESS;
    }
    else {
        SetLastError(ReturnCode);
        return SOCKET_ERROR;
    }
}
Beispiel #6
0
int
WSPAPI
WSCWriteNameSpaceOrder (
    IN LPGUID lpProviderId,
    IN DWORD dwNumberOfEntries
    )
/*++

Routine Description:

    Reorder existing WinSock2 name space providers.  The order of the service
    providers determines their priority in being selected for use.  The
    sporder.exe tool will show you the installed provider and their ordering,
    Alternately, WSAEnumNameSpaces(), in conjunction with this function,
    will allow you to write your own tool.

Arguments:

    lpwdCatalogEntryId  [in]
      An array of CatalogEntryId elements as found in the WSAPROTOCOL_INFO
      structure.  The order of the CatalogEntryId elements is the new
      priority ordering for the service providers.

    dwNumberOfEntries  [in]
      The number of elements in the lpwdCatalogEntryId array.


Return Value:

    ERROR_SUCCESS   - the service providers have been reordered.
    WSAEINVAL       - input parameters were bad, no action was taken.
    WSAEFAULT       - CatalogEnryId array is not fully contained within
                        process address space.
    WSATRY_AGAIN    - the routine is being called by another thread or process.
    any registry error code


Comments:

    Here are scenarios in which the WSCWriteProviderOrder function may fail:

      The dwNumberOfEntries is not equal to the number of registered service
      providers.

      The lpwdCatalogEntryId contains an invalid catalog ID.

      The lpwdCatalogEntryId does not contain all valid catalog IDs exactly
      1 time.

      The routine is not able to access the registry for some reason
      (e.g. inadequate user persmissions)

      Another process (or thread) is currently calling the routine.


--*/
{
    INT             errno_result;
    HKEY            registry_root;
    PNSCATALOGENTRY item;
    PNSCATALOGENTRY *items = NULL;
    DWORD           i;

    // object protected by "try" block
    PNSCATALOG           catalog = NULL;


    items = new PNSCATALOGENTRY[dwNumberOfEntries];
    if (items==NULL) {
        DEBUGF(
            DBG_ERR,
            ("Allocating items array\n"));
        return WSA_NOT_ENOUGH_MEMORY;
    }

    memset (items, 0, sizeof (PNSCATALOGENTRY)*dwNumberOfEntries);

    errno_result = ERROR_SUCCESS;

    TRY_START(guard_memalloc) {
        PROVIDER_SNAP_CONTEXT context;
        registry_root = OpenWinSockRegistryRoot();
        if (registry_root == NULL) {
            DEBUGF(
                DBG_ERR,
                ("Opening registry root\n"));
            errno_result = WSANO_RECOVERY;
            TRY_THROW(guard_memalloc);
        }

        catalog = new NSCATALOG();
        if (catalog == NULL) {
            errno_result = WSA_NOT_ENOUGH_MEMORY;
            TRY_THROW(guard_memalloc);
        }

        errno_result = catalog->InitializeFromRegistry(
            registry_root,  // ParentKey
            NULL            // ChangeEvent
            );
        if (errno_result != ERROR_SUCCESS) {
            TRY_THROW(guard_memalloc);
        }

        context.Items = items;
        context.ProviderIds = lpProviderId;
        context.Count = dwNumberOfEntries;
        context.ErrorCode = ERROR_SUCCESS;

        catalog->EnumerateCatalogItems(
            ProviderSnap,         // Iteration
            & context               // PassBack
            );
        if (context.ErrorCode!=ERROR_SUCCESS) {
            errno_result = context.ErrorCode;
            TRY_THROW(guard_memalloc);
        }

        for (i=0; i<dwNumberOfEntries; i++) {
            if (context.Items[i]!=NULL) {
                //
                // Remove catalog item and add it in the end.
                //
                catalog->RemoveCatalogItem (context.Items[i]);
                catalog->AppendCatalogItem (context.Items[i]);
            }
            else {
                DEBUGF (DBG_ERR,
                    ("Checking item array against catalog, item: %ld.\n",
                    i));
                errno_result = WSAEINVAL;
                TRY_THROW(guard_memalloc);
            }
        } // for i

        errno_result = catalog->WriteToRegistry();
        if (errno_result!=ERROR_SUCCESS) {
            TRY_THROW(guard_memalloc);
        }

        delete catalog;
        CloseWinSockRegistryRoot(registry_root);

    } TRY_CATCH(guard_memalloc) {
        assert (errno_result != ERROR_SUCCESS);
        if (catalog != NULL) {
            delete catalog; // This destroys the items as well
        }
        
        if (registry_root!=NULL) {
            CloseWinSockRegistryRoot(registry_root);
        }
    } TRY_END(guard_memalloc);


    delete items;

    if (errno_result == ERROR_SUCCESS) {
        HANDLE hHelper;

        //
        // Alert all interested apps of change via the notification method
        //

        if (WahOpenNotificationHandleHelper( &hHelper) == ERROR_SUCCESS) {
            WahNotifyAllProcesses( hHelper );
            WahCloseNotificationHandleHelper( hHelper );
        }
        else {
            //
            // This in non-fatal and catalog was updated anyway.
            //
        }
    }

    return errno_result;
}
Beispiel #7
0
INT WSAAPI
WSCEnableNSProvider (
    IN  LPGUID  lpProviderId,
    IN  BOOL    fEnable
    )
/*++

Routine Description:

    WSCEnableNSProvider() is used to change the state of a given name space
    provider.  This function is intended to be used by the control panel applet
    to change the state of the providers.  An ISV should not just blindly
    de-activate another ISV's provider in order to activate their own.  This
    choice should be left up to the user.description-of-function

Arguments:

    lpProviderId - The unique identifier for this provider.

    fEnable - If TRUE, the provider is set to the active state.  If FALSE, the
              provider is disabled and will not be available for query
              operations or service registration.

Return Value:

    The function should return NO_ERROR (0) if the routine succeeds.  It should
    return SOCKET_ERROR (-1) if the routine fails and it must set the
    appropriate error code using SetLastError().

--*/
{
    INT                  ReturnCode;
    PNSCATALOG           Catalog =NULL;
    HKEY                 registry_root;

    registry_root = OpenWinSockRegistryRoot();
    if (NULL == registry_root) {
        DEBUGF(
            DBG_ERR,
            ("Opening registry root\n"));
        SetLastError(WSASYSCALLFAILURE);
        return(SOCKET_ERROR);
    }

    TRY_START(guard_memalloc){
        GUID_MATCH_CONTEXT     context;

        Catalog = new NSCATALOG;
        if (NULL == Catalog){
            ReturnCode = WSA_NOT_ENOUGH_MEMORY;
            TRY_THROW(guard_memalloc);
        } //item


        ReturnCode = Catalog->InitializeFromRegistry(
                        registry_root,  // ParentKey
                        NULL            // ChangeEvent
                        );

        if (ERROR_SUCCESS != ReturnCode){
            TRY_THROW(guard_memalloc);
        } //if

        __try {
            context.ProviderId = *lpProviderId;
        }
        __except (WS2_EXCEPTION_FILTER()) {
            ReturnCode = WSAEFAULT;
            TRY_THROW(guard_memalloc);
        }

        context.CatalogItem = NULL;
        Catalog->EnumerateCatalogItems(
            GuidMatcher,
            &context);

        if (context.CatalogItem!=NULL) {
            context.CatalogItem->Enable (fEnable ? TRUE : FALSE);
        }
        else {
            ReturnCode = WSAEINVAL;
            TRY_THROW(guard_memalloc);
        }

        ReturnCode = Catalog->WriteToRegistry();
        if (ReturnCode != ERROR_SUCCESS) {
            TRY_THROW(guard_memalloc);
        }

        delete Catalog;

    } TRY_CATCH(guard_memalloc){

        assert (ReturnCode!=ERROR_SUCCESS);
        if (Catalog){
            delete Catalog;
        } //if
    } TRY_END(guard_memalloc);

    CloseWinSockRegistryRoot(registry_root);

    if (ERROR_SUCCESS == ReturnCode){
        HANDLE hHelper;

        //
        // Alert all interested apps of change via the notification method
        //

        if (WahOpenNotificationHandleHelper( &hHelper) == ERROR_SUCCESS) {
            WahNotifyAllProcesses( hHelper );
            WahCloseNotificationHandleHelper( hHelper );
        }
        else {
            //
            // This in non-fatal and catalog was updated anyway.
            //
        }

        return ERROR_SUCCESS;
    } 
    else {
        SetLastError(ReturnCode);
        return SOCKET_ERROR;
    }

}
Beispiel #8
0
INT
WSAAPI
WSCUnInstallNameSpace (
    IN  LPGUID  lpProviderId
    )
/*++

Routine Description:

    WSCUnInstallNameSpace() is used to uninstall the indicated name space
    provider.

Arguments:

    lpProviderId - The unique identifier for a provider.

Return Value:

    The function should return NO_ERROR (0) if the routine succeeds.  It should
    return SOCKET_ERROR (-1) if the routine fails and it must set the
    appropriate error code using SetLastError().
--*/
{
    INT                  ReturnCode;
    PNSCATALOG           Catalog =NULL;
    HKEY                 registry_root;

    //Open and Initialize a name space jprovider catalog
    registry_root = OpenWinSockRegistryRoot();
    if (NULL == registry_root) {
        DEBUGF(
            DBG_ERR,
            ("Opening registry root\n"));
        SetLastError(WSASYSCALLFAILURE);
        return(SOCKET_ERROR);
    }

    TRY_START(guard_memalloc){
        GUID_MATCH_CONTEXT     context;
        Catalog = new NSCATALOG;
        if (NULL == Catalog){
            ReturnCode = WSA_NOT_ENOUGH_MEMORY;
            TRY_THROW(guard_memalloc);
        } //item


        ReturnCode = Catalog->InitializeFromRegistry(
                            registry_root,  // ParentKey
                            NULL            // ChangeEvent
                            );
        if (ERROR_SUCCESS != ReturnCode){
            TRY_THROW(guard_memalloc);
        } //if

        __try {
            context.ProviderId = *lpProviderId;
        }
        __except (WS2_EXCEPTION_FILTER()) {
            ReturnCode = WSAEFAULT;
            TRY_THROW(guard_memalloc);
        }

        context.CatalogItem = NULL;
        Catalog->EnumerateCatalogItems(
            GuidMatcher,
            &context);

        if (context.CatalogItem!=NULL) {
            Catalog->RemoveCatalogItem (context.CatalogItem);
            context.CatalogItem->Dereference ();
        }
        else {
            ReturnCode = WSAEINVAL;
            TRY_THROW(guard_memalloc);
        }

        ReturnCode = Catalog->WriteToRegistry();

        if (ERROR_SUCCESS != ReturnCode){
            TRY_THROW(guard_memalloc);
        } //if

        delete Catalog;
    } TRY_CATCH(guard_memalloc){
        assert (ReturnCode!=ERROR_SUCCESS);
        if (Catalog){
            delete Catalog;
        } //if
    } TRY_END(guard_memalloc);

    CloseWinSockRegistryRoot(registry_root);

    if (ERROR_SUCCESS == ReturnCode){
        HANDLE hHelper;

        //
        // Alert all interested apps of change via the notification method
        //

        if (WahOpenNotificationHandleHelper( &hHelper) == ERROR_SUCCESS) {
            WahNotifyAllProcesses( hHelper );
            WahCloseNotificationHandleHelper( hHelper );
        }
        else {
            //
            // This in non-fatal and catalog was updated anyway.
            //
        }

        return ERROR_SUCCESS;
    } 
    else {
        SetLastError(ReturnCode);
        return SOCKET_ERROR;
    }
}