Exemplo n.º 1
0
void main(int argc, char *argv[])
{
	if(argc==2)
	{
		if(strcmp(argv[1], "-install")==0)   
		{
			TCHAR szPathName[256];
			TCHAR* p;

			if(::GetFullPathName(L"LSP.dll", 256, szPathName, &p) != 0)
			{
				if(InstallProvider(szPathName))
				{
					printf(" Install successully. \n");
					return;
				}
			}
			printf(" Install failed. \n");
			return;
		}
		else if(strcmp(argv[1],"-remove")==0)  
		{
			if(RemoveProvider())
				printf(" Deinstall successully. \n");
			else
				printf(" Deinstall failed. \n");
			return;
		}
	}
	
	printf(" Usage: Instlsp [ -install │ -remove ] \n");
}
Exemplo n.º 2
0
void CSyssetPage::OnInstall()				// 用户点击"安装"按钮
{
	TCHAR szPathName[256];
	TCHAR* p;

	// 注意,安装LSP需要使用完整DLL路径。这样的话,CPIOControl类在加载DLL时也应使用
	// 完整路径,否则CPIOControl类加载的DLL不能和作为LSP的DLL共享内存
	if(::GetFullPathName(PHOENIX_SERVICE_DLL_NAME, 256, szPathName, &p) != 0)
	{
		if(InstallProvider(szPathName))
		{
			MessageBox(L" 应用层过滤安装成功!"); 
			return;
		}
	}
	MessageBox(L" 应用层过滤安装失败!"); 
}
Exemplo n.º 3
0
void main(int argc, char *argv[])
{
	char szFileName[256];
	char szPathName[256];
	char* p;
	
	if(argc == 3)
	{
		strcpy(szFileName,argv[2]);
		if(strcmp(argv[1], "-install")==0)   
		{
			if(::GetFileAttributes(szFileName) == -1)
			{
				printf("Error:Can't Find File!\n");
				return;
			}
			
			if(::GetFullPathName(szFileName, 256, szPathName, &p) != 0)
			{
				if(InstallProvider(szPathName))
				{
					printf("\nInstall Successully!\n");
					return;
				}
			}
			printf("\nInstall Failed -> %d\n",::GetLastError());
			return;
		}
		else if(strcmp(argv[1],"-remove")==0)  
		{
			if(RemoveProvider())
				printf("\nRemove Successully!\n");
			else
				printf("\nRemove Failed -> %d\n",::GetLastError());
			return;
		}
	}
	printf(" Usage: test.exe [ -install │ -remove ] DllName\n");
	printf("\n\teg:test.exe -install LSP.dll\n");
	printf("\tor:test.exe -remove  LSP.dll\n");
	printf("\n");
}
Exemplo n.º 4
0
//
// Function: InstallNonIfsLspProtocolChains
//
// Description:
//      This function builds and install the protocol chain entries associated with
//      a non-IFS LSP. The caling routine installs the dummy, hidden entry in the
//      catalog and this routine enumerates the catalog, finds the dummy entry,
//      builds the layered chain entries, and installs them into the catalog.
//
int
InstallNonIfsLspProtocolChains(
    WINSOCK_CATALOG eCatalog,
    GUID           *Guid,
    WCHAR          *lpszLspName,
    WCHAR          *lpszLspFullPathAndFile,
    DWORD          *pdwCatalogIdArray,
    DWORD           dwCatalogIdArrayCount
    )
{
    WSAPROTOCOL_INFOW   *pProvider = NULL,
                        *pLayeredEntries = NULL;
    DWORD                dwDummyLspId = 0;
    INT                  iProviderCount = 0,
                         retval = SOCKET_ERROR,
                         idx,
                         err,
                         rc,
                         i, j;
    HRESULT              hr;

    // Enumerate the catalog
    pProvider = EnumerateProviders( eCatalog, &iProviderCount );
    if ( NULL == pProvider )
    {
        fprintf( stderr, "InstallNonIfsLspProtocolChain: Unable to enumerate catalog\n" );
        goto cleanup;
    }

    pLayeredEntries = (WSAPROTOCOL_INFOW *) LspAlloc( sizeof(WSAPROTOCOL_INFOW) *
            dwCatalogIdArrayCount, &err );
    if ( NULL == pLayeredEntries )
    {
        fprintf( stderr, "InstallNonIfsLspProtocolChain: LspAlloc failed: %d\n", err );
        goto cleanup;
    }

    // Find the dummy entry so we can extract its catalog ID
    dwDummyLspId = GetCatalogIdForProviderGuid( Guid, pProvider, iProviderCount );

    ASSERT( dwDummyLspId != 0 );

    // Go through the catalog and build the layered entries
    idx = 0;
    for(i=0; i < iProviderCount ;i++)
    {
        for(j=0; j < (int) dwCatalogIdArrayCount ;j++)
        {
            if ( pProvider[ i ].dwCatalogEntryId == pdwCatalogIdArray[ j ] )
            {
                if ( pProvider[ i ].ProtocolChain.ChainLen >= ( MAX_PROTOCOL_CHAIN - 1 ) )
                {
                    fprintf( stderr, "InstallNonIfsLspProtocolchain: Too many LSPs installed!\n");
                    goto cleanup;
                }

                memcpy( &pLayeredEntries[ idx ], &pProvider[ i ], sizeof( WSAPROTOCOL_INFOW ) );

                // Put our LSP name in the protocol field
                hr = StringCchPrintfW( pLayeredEntries[ idx ].szProtocol, WSAPROTOCOL_LEN,
                        L"%s over [%s]",
                        lpszLspName,
                        pProvider[ i ].szProtocol
                        );
                if ( FAILED( hr ) )
                {
                    fprintf( stderr, "InstallNonIfsLspProtocolChain: StringCchPrintfW failed: 0x%x\n", hr );
                    goto cleanup;
                }

                // Move all the protocol chain entries down by 1 position and insert 
                // the dummy entry id at the head
                InsertIdIntoProtocolChain( &pLayeredEntries[ idx ], 0, dwDummyLspId );

                // The second entry is always the ID of the current pProvider[i]
                //     In case of multiple LSPs then if we didn't do this the [1] index
                //     would contain the ID of that LSP's dummy entry and not the entry
                //     itself.
                pLayeredEntries[ idx ].ProtocolChain.ChainEntries[ 1 ] = 
                        pProvider[ i ].dwCatalogEntryId;

                // Remove the IFS flag 
                pLayeredEntries[ idx ].dwServiceFlags1 &= (~XP1_IFS_HANDLES);

                idx++;
            }
        }
    }

    for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
    {
        // Create a GUID for the protocol chain entries
        if ( UuidCreate( &pLayeredEntries[ i ].ProviderId ) != RPC_S_OK )
        {
            fprintf(stderr, "InstallNonIfsLspProtocolChains: UuidCreate failed: %d\n", GetLastError());
            goto cleanup;
        }

        // Install the layered chain providers
        rc = InstallProvider(
                eCatalog, 
               &pLayeredEntries[ i ].ProviderId, 
                lpszLspFullPathAndFile,
               &pLayeredEntries[ i ], 
                1
                );
        if ( NO_ERROR != rc )
        {
            fprintf(stderr, "InstallNonIfsLspProtocolChains: Unable to install layered chain entries!\n");
            goto cleanup;
        }
    }

    // Reorder the winsock catalog so the layered chain entries appear first
    rc = ReorderCatalog( eCatalog, dwDummyLspId );
    if ( NO_ERROR != rc )
    {
        fprintf(stderr, "InstallNonIfsLspProtocolChains: Unable to reorder Winsock catalog!\n");
        goto cleanup;
    }

    retval = NO_ERROR;

cleanup:

    if ( NULL != pProvider )
        FreeProviders( pProvider );

    if ( NULL != pLayeredEntries )
        LspFree( pLayeredEntries );

    return retval;
}
Exemplo n.º 5
0
//
// Function: InstallIfsLspProtocolChains
//
// Description:
//      This routine installs the layered protocol chains for an IFS based LSP. It
//      assumes the LSP dummy entry is already installed. This function first enumerates
//      the catalog to find the ID of the dummy entry. It then builds the protocol
//      entries for the IFS layered protocols. Note that an IFS entry must be installed
//      such that no non-IFS providers are layered beneath it. This means if the user
//      chooses to install the IFS LSP over a provider which includes non-IFS layers, it
//      must insert itself into the chain such that it is below all non-IFS providers.
//      This means that existing entries need to be modified in order to reflect this
//      ordering. Also in the event that the IFS LSP is inserted into an existing chain
//      this installer still builds a series of standalone entries (i.e. entries that
//      would have existed of the LSPs layered over the IFS LSP were installed after
//      the IFS LSP was).
//
int
InstallIfsLspProtocolChains(
    WINSOCK_CATALOG eCatalog,
    GUID           *Guid,
    WCHAR          *lpszLspName,
    WCHAR          *lpszLspFullPathAndFile,
    DWORD          *pdwCatalogIdArray,
    DWORD           dwCatalogIdArrayCount
    )
{
    WSAPROTOCOL_INFOW  *pProvider = NULL,
                       *pProviderNew = NULL,
                       *pLayeredEntries = NULL,
                       *pEntry = NULL,
                        TempEntry = {0};
    DWORD              *pProviderOrder = NULL,
                        dwDummyLspId;
    WCHAR               wszLspDll[ MAX_PATH ];
    BOOL                bLayeredOverNonIfs = FALSE,
                        bContainsNonIfs = FALSE;
    HRESULT             hr;
    int                 ProviderPathLen = MAX_PATH-1,
                        iProviderCount,
                        iProviderCountNew,
                        LayerIdx,
                        retval = SOCKET_ERROR,
                        err,
                        idx,
                        rc,
                        i, j, k;

    // Enumerate the catalog
    pProvider = EnumerateProviders( eCatalog, &iProviderCount );
    if ( NULL == pProvider )
    {
        fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" );
        goto cleanup;
    }

    // Find the dummy, hidden entry of our new LSP
    dwDummyLspId = GetCatalogIdForProviderGuid( Guid, pProvider, iProviderCount );

    ASSERT( dwDummyLspId != 0 );

    // Allocate space for the protocol chains of the new LSP
    pLayeredEntries = (WSAPROTOCOL_INFOW *) LspAlloc( sizeof(WSAPROTOCOL_INFOW) *
            dwCatalogIdArrayCount, &err );
    if ( NULL == pLayeredEntries )
    {
        fprintf( stderr, "InstallIfsLspProtocolChains: LspAlloc failed: %d\n", err );
        goto cleanup;
    }

    LayerIdx = 0;

    // Build the layered protocol entries as well as a list of those providers which
    // require modification. Whenever an LSP is installed, a number of protocol entries
    // are installed where the first entry in the chain array is the LSP's dummy entry.
    // Addtionally, if we're installing an IFS LSP over an provider whose protocol chain
    // includes non-IFS LSPs, the IFS LSP must be placed in the chain such that no
    // non-IFS LSPs are positioned after it in the chain.

    // Loop through each ID we're layering over
    for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
    {
        for(j=0; j < iProviderCount ;j++)
        {
            printf("Matching selected ID %d to catalog %d\n",
                    pdwCatalogIdArray[ i ], pProvider[ j ].dwCatalogEntryId );

            if ( pdwCatalogIdArray[ i ] == pProvider[ j ].dwCatalogEntryId )
            {
                // Verify the entry has room enough to be layered over
                if ( pProvider[ j ].ProtocolChain.ChainLen >= ( MAX_PROTOCOL_CHAIN - 1 ) )
                {
                    fprintf( stderr, "InstallIfsLspProtocolChain: Too many LSPs installed!\n");
                    goto cleanup;
                }

                // Save off the entry which we're layering over
                memcpy( &pLayeredEntries[ LayerIdx ], &pProvider[ j ],
                        sizeof( pLayeredEntries[ 0  ] ) );

                memcpy( &TempEntry, &pProvider[ j ], sizeof( TempEntry ) );        

                // Fill in the new LSP entry's name
                hr = StringCchPrintfW( pLayeredEntries[ LayerIdx ].szProtocol, WSAPROTOCOL_LEN,
                        L"%s over [%s]",
                        lpszLspName,
                        pProvider[ j ].szProtocol 
                        );
                if ( FAILED( hr ) )
                {
                    fprintf( stderr, "InstallIfsLspProtocolChains: StringCchPrintfW failed: 0x%x\n", hr );
                    goto cleanup;
                }

                // Check whether the selected entry contains non IFS LSPs in its chain
                if ( pProvider[ j ].ProtocolChain.ChainLen >= 2 )
                {
                    for(k=pProvider[ j ].ProtocolChain.ChainLen-2 ; k >= 0 ;k--)
                    {
                        bContainsNonIfs = IsNonIfsProvider( pProvider, iProviderCount, 
                                pProvider[ j ].ProtocolChain.ChainEntries[ k ] );

                        if ( TRUE == bContainsNonIfs )
                        {
                            // Need to modify the pProvider entry to reference the
                            // added LSP entry within its chain

                            // In the 'modified' array make a space at location after 'k'
                            InsertIdIntoProtocolChain( &pProvider[ j ], k+1, UPDATE_LSP_ENTRY );

                            // Save the index to the layer which corresponds to this entry
                            pProvider[ j ].dwProviderReserved = LayerIdx + 1;

                            // Need to fix the 'pLayeredEntry' as well
                            BuildSubsetLspChain( &pLayeredEntries[ LayerIdx ], k+1, dwDummyLspId );

                            pLayeredEntries[ LayerIdx ].dwServiceFlags1 |= XP1_IFS_HANDLES;

                            bLayeredOverNonIfs = TRUE;

                            // Need to insert the IFS provider in all LSPs that  are layered
                            // above the location where the IFS provider was just inserted
                            InsertIfsLspIntoAllChains( &TempEntry, pProvider, iProviderCount, 
                                    LayerIdx + 1, k );

                            break;
                        }
                    }
                }

                // Need to setup the protocol chain in the pLayeredEntry if we haven't
                // already done so above
                if ( TRUE != bContainsNonIfs )
                {
                    InsertIdIntoProtocolChain( &pLayeredEntries[ LayerIdx ], 0, dwDummyLspId );

                    // The second entry is always the ID of the current pProvider[i]
                    //     In case of multiple LSPs then if we didn't do this the [1] index
                    //     would contain the ID of that LSP's dummy entry and not the entry
                    //     itself.
                    pLayeredEntries[ LayerIdx ].ProtocolChain.ChainEntries[ 1 ] = 
                            TempEntry.dwCatalogEntryId;

                    pLayeredEntries[ LayerIdx ].dwServiceFlags1 |= XP1_IFS_HANDLES;
                }

                LayerIdx++;
            }
        }
    }

    ASSERT( LayerIdx == (int)dwCatalogIdArrayCount );

    // Create a unique GUID for each provider to install and install it
    for(i=0;i < (int)dwCatalogIdArrayCount ;i++)
    {
        if ( RPC_S_OK != UuidCreate( &pLayeredEntries[ i ].ProviderId ) )
        {
            fprintf(stderr, "InstallIfsLspProtocolChains: UuidCreate failed: %d\n", GetLastError());
            goto cleanup;
        }

        rc = InstallProvider( eCatalog, &pLayeredEntries[ i ].ProviderId,
                lpszLspFullPathAndFile, &pLayeredEntries[ i ], 1 );
        if ( NO_ERROR != rc )
        {
            fprintf(stderr, "InstallIfsLspProtocolChains: Unable to install the dummy LSP entry!\n");
            goto cleanup;
        }
    }

    if ( TRUE == bLayeredOverNonIfs )
    {
        // Enumerate the catalog again so we can find the catalog IDs

        pProviderNew = EnumerateProviders( eCatalog, &iProviderCountNew );
        if ( NULL == pProvider )
        {
            fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" );
            goto cleanup;
        }

        for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
        {
            pLayeredEntries[ i ].dwCatalogEntryId = GetCatalogIdForProviderGuid(
                   &pLayeredEntries[ i ].ProviderId,
                    pProviderNew,
                    iProviderCountNew
                    );

            ASSERT( pLayeredEntries[ i ].dwCatalogEntryId != 0 );
        }

        // Update the protocol chains of the modified entries to point to the just
        //    installed providers
        for(i=0; i < iProviderCount ;i++)
        {
            if ( pProvider[ i ].dwProviderReserved == 0 )
                continue;

            for(j=0; j < pProvider[ i ].ProtocolChain.ChainLen ;j++)
            {
                if ( UPDATE_LSP_ENTRY == pProvider[ i ].ProtocolChain.ChainEntries[ j ] )
                {
                    pProvider[ i ].ProtocolChain.ChainEntries[ j ] = 
                        pLayeredEntries[ pProvider[ i ].dwProviderReserved - 1 ].dwCatalogEntryId;

                    pProvider[ i ].dwProviderReserved = 0;
                }
            }

            // Get the DLL path
            ProviderPathLen = MAX_PATH-1;
            rc = WSCGetProviderPath(
                    &pProvider[ i ].ProviderId,
                     wszLspDll,
                    &ProviderPathLen,
                    &err
                     );
            if ( SOCKET_ERROR == rc )
            {
                fprintf( stderr, "InstallIfsLspProtocolChains: WSCGetProviderPath failed: %d\n", err );
                goto cleanup;
            }

            // Update the providers which were modified
            rc = UpdateProvider( eCatalog, &pProvider[ i ].ProviderId,
                    wszLspDll, &pProvider[ i ], 1, &err );
            if ( SOCKET_ERROR == rc )
            {
                fprintf( stderr, "InstallIfsLspProtocolChains: UpdateProvider failed: %d\n", err );
                goto cleanup;
            }

            printf("Updated entry ID: %d: %S (chain len = %d)\n",
                    pProvider[ i ].dwCatalogEntryId,
                    pProvider[ i ].szProtocol,
                    pProvider[ i ].ProtocolChain.ChainLen
                    );
        }

        FreeProviders( pProvider );
        pProvider = NULL;

        FreeProviders( pProviderNew );
        pProviderNew = NULL;

        /*
        {
            WSADATA wsd;

            WSACleanup();

            WSAStartup( MAKEWORD(2,2), &wsd );
        }
        */

        pProvider = EnumerateProviders( eCatalog, &iProviderCount );
        if ( NULL == pProvider )
        {
            fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" );
            goto cleanup;
        }

        // Allocate an array of DWORDs to contain the new catalog ordering
        pProviderOrder = (DWORD *)LspAlloc( iProviderCount * sizeof(DWORD), &err );
        if ( NULL == pProviderOrder )
        {
            fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" );
            goto cleanup;
        }

        // First add the entries we layered over first
        idx = 0;
        for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
        {
            pEntry = FindProviderById( pdwCatalogIdArray[ i ], pProvider, iProviderCount );
            if ( NULL == pEntry )
            {
                fprintf(stderr, "InstallIfsLspProtocolChain: Unable to find entry to reorder catalog!\n");
                goto cleanup;
            }

            pEntry->dwProviderReserved = 1;

            pProviderOrder[ idx++ ] = pEntry->dwCatalogEntryId;
        }

        // Now go through the protocol chain of the entries we layered over and put those
        //    LSP entries next in the new order
        for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
        {
            pEntry = FindProviderById( pdwCatalogIdArray[ i ], pProvider, iProviderCount );
            if ( NULL == pEntry )
            {
                fprintf(stderr, "InstallIfsLspProtocolChain: Unable to find entry to reorder catalog!\n");
                goto cleanup;
            }

            printf("Looping through: %d: %S (chain len = %d)\n", 
                    pEntry->dwCatalogEntryId,
                    pEntry->szProtocol,
                    pEntry->ProtocolChain.ChainLen );

            for(j=1; j < pEntry->ProtocolChain.ChainLen-1 ;j++)
            {
                dwDummyLspId = FindDummyIdFromProtocolChainId(
                        pEntry->ProtocolChain.ChainEntries[ j ],
                        pProvider,
                        iProviderCount
                        );

                printf("   Finding dummy ID for chain entry: %d is %d\n", 
                        pEntry->ProtocolChain.ChainEntries[ j ],
                        dwDummyLspId
                        );

                for(k=0; k < iProviderCount ;k++)
                {
                    if ( ( pProvider[ k ].ProtocolChain.ChainLen >= 2 ) &&
                         ( pProvider[ k ].ProtocolChain.ChainEntries[ 0 ] == dwDummyLspId ) &&
                         ( pProvider[ k ].dwProviderReserved == 0 )
                       )
                    {
                        pProviderOrder[ idx++ ] = pProvider[ k ].dwCatalogEntryId;
                        pProvider[ k ].dwProviderReserved = 1;

                        printf("      Adding: %d\n", pProvider[ k ].dwCatalogEntryId );
                    }
                }
            }
        }

        // Now any catalog entry that wasn't already copied, copy it
        for(i=0; i < iProviderCount ;i++)
        {
            if ( pProvider[ i ].dwProviderReserved == 0 )
                pProviderOrder[ idx++ ] = pProvider[ i ].dwCatalogEntryId;
        }

        ASSERT( idx == iProviderCount );

        // Write the new catalog order
        rc = WriteProviderOrder( eCatalog, pProviderOrder, iProviderCount, &err );
        if ( NO_ERROR != rc )
        {
            fprintf( stderr, "InstallIfsLspProtocolChains: WriteProviderOrder failed: %d\n",
                    err );
            goto cleanup;
        }
    }
    else
    {
        //
        // Reorder the winsock catalog so the layered chain entries appear first.
        // Since we didn't have to modify any existing entries, all we need to do is
        //    move the added entries to the head of the catalog
        // 
        rc = ReorderCatalog( eCatalog, dwDummyLspId );
        if ( NO_ERROR != rc )
        {
            fprintf(stderr, "InstallIfsLspProtocolChains: Unable to reorder Winsock catalog!\n");
            goto cleanup;
        }
    }

    retval = NO_ERROR;

cleanup:
    
    if ( NULL != pProvider )
    {
        FreeProviders( pProvider );
        pProvider = NULL;
    }

    if ( NULL != pProviderNew )
    {
        FreeProviders( pProviderNew );
        pProviderNew = NULL;
    }

    if ( NULL != pProviderOrder )
    {
        LspFree( pProviderOrder );
        pProviderOrder = NULL;
    }

    return retval;
}
Exemplo n.º 6
0
//
// Function: InstallLsp
//
// Description:
//    This function installs the LSP over each of the catalog IDs supplied in
//    the pdwCatalogIdArray into the given Winsock catalog (since there are
//    two catalogs on WIN64 platforms). This routine first installs the layered
//    protocol entry (the dummy hidden provider) followed by installing the
//    layered protocol chains.
//
int
InstallLsp(
    WINSOCK_CATALOG eCatalog,               // Which catalog to install LSP into
    char           *lpszLspName,            // String name of LSP
    char           *lpszLspPathAndFile,     // Location of LSP dll and dll name
    DWORD           dwCatalogIdArrayCount,  // Number of entries in pdwCatalogIdArray
    DWORD          *pdwCatalogIdArray,      // Array of IDs to install over
    BOOL            IfsProvider
    )
{
    WSAPROTOCOL_INFOW  *pProtocolInfo = NULL,
                       *pDummyEntry = NULL,
                       *pLayeredEntries = NULL;
    WCHAR               wszLspName[ WSAPROTOCOL_LEN ],
                        wszFullProviderPath[ MAX_PATH+1 ];
    GUID                ProviderBaseGuid;
    INT                 rc = SOCKET_ERROR;

    //
    // Install the LSP over the given entries. If selected to install over all
    // entries, then enumerate the catalog to obtain all the available providers.
    //

    if ( NULL == lpszLspName )
    {
        lpszLspName = DEFAULT_LSP_NAME;
    }

    // Convert the LSP name to UNICODE since the Winsock catalog is all UNICODE
    rc = MultiByteToWideChar(
            CP_ACP, 
            0, 
            lpszLspName, 
            (int) strlen( lpszLspName ) + 1,
            wszLspName, 
            WSAPROTOCOL_LEN 
            );
    if (rc == 0)
    {
        fprintf(stderr, "InstallLsp: MultiByteToWideChar failed to convert '%s'; Error = %d\n",
                lpszLspName, GetLastError());
        goto cleanup;
    }

    rc = MultiByteToWideChar(
            CP_ACP,
            0,
            lpszLspPathAndFile,
            (int) strlen( lpszLspPathAndFile ) + 1,
            wszFullProviderPath,
            MAX_PATH
            );
    if ( 0 == rc )
    {
        fprintf( stderr, "InstallLsp: MultiByteToWidechar failed to convert '%s': Error = %d\n",
                lpszLspPathAndFile, GetLastError() );
        goto cleanup;
    }

    // Verify there's at least one entry to layer over
    if ( 0 == dwCatalogIdArrayCount )
    {
        fprintf(stderr, "InstallLsp: Error! Must specify at least one provider to layer over!\n\n");
        goto cleanup;
    }

    printf("LSP name is '%S'\n", wszLspName);

    // Create the 'dummy' protocol entry
    pDummyEntry = CreateDummyEntry( eCatalog, pdwCatalogIdArray[ 0 ], wszLspName, IfsProvider );
    if (pDummyEntry == NULL)
    {
        fprintf(stderr, "InstallLsp: CreateDummyEntry failed!\n");
        goto cleanup;
    }

    RetrieveLspGuid( lpszLspPathAndFile, &ProviderBaseGuid );

    // Install the 'dummy' protocol entry for the LSP
    rc = InstallProvider(
            eCatalog, 
           &ProviderBaseGuid, 
            wszFullProviderPath, 
            pDummyEntry, 
            1
            );
    if ( NO_ERROR != rc )
    {
        fprintf(stderr, "InstallLsp: Unable to install the dummy LSP entry!\n");
        goto cleanup;
    }

    // Don't need this struture any more
    LspFree( pDummyEntry );
    pDummyEntry = NULL;

    if ( FALSE == IfsProvider )
    {
        rc = InstallNonIfsLspProtocolChains( eCatalog, &ProviderBaseGuid, wszLspName,
                wszFullProviderPath, pdwCatalogIdArray, dwCatalogIdArrayCount );
                
    }
    else
    {
        rc = InstallIfsLspProtocolChains( eCatalog, &ProviderBaseGuid, wszLspName,
                wszFullProviderPath, pdwCatalogIdArray, dwCatalogIdArrayCount );
    }

    if ( SOCKET_ERROR == rc )
    {
        // An error occured installing the chains so remove the dummy entry
        DeinstallProvider( eCatalog, &ProviderBaseGuid );
    }

cleanup:

    if ( NULL != pProtocolInfo )
        FreeProviders( pProtocolInfo );

    if ( NULL != pDummyEntry )
        LspFree( pDummyEntry );

    if ( NULL != pLayeredEntries )
        LspFree( pLayeredEntries );

    return rc;
}
Exemplo n.º 7
0
//
// Function: RemoveProvider
//
// Description:
//    This function removes a layered provider. Things can get tricky if
//    we're removing a layered provider which has been layered over by
//    another provider. This routine first creates the LSP map to determine
//    if other LSPs on the system reference the LSP we want to remove. If
//    there are we must fix those LSPs before deleting the target LSP.
//    If we're on a platform that supports WSCUpdateProvider its simply a
//    matter of removing any reference to the target LSP's layered protocol
//    chains and the dummy hidden entry.
//
//    If we're not on a WSCUpdateProvider enabled system, then its very tricky.
//    We must uninstall the dependent LSPs first followed by reinstalling them
//    in the same order they were originally installed. For example if LSP1,
//    LSP2, and LSP3 are installed (in that order) and this routine is invoked
//    to remove LSP1, we must uninstall LSP3 and LSP2 followed by re-installing
//    (LSP2 first then LSP3). For each LSP added back we must fix up the protocol
//    chains of the next higher LSP so the reference the new catalog IDs (since
//    the action of installing an LSP assigns a new catalog ID).
//
//    NOTE: If WSCUpdateProvider is not supported there is the possiblity of
//          another process changing the Winsock catalog at the same time we're
//          trying to fix it back up. If this occurs it is possible for the
//          corruption to occur.
//
int
RemoveProvider(
    WINSOCK_CATALOG Catalog,            // Catalog to remove an LSP from
    DWORD           dwProviderId        // Catalog ID of LSPs hidden entry
)
{
    WSAPROTOCOL_INFOW   *pProvider = NULL,
                         *pLayeredEntries = NULL;
    LSP_ENTRY           *pLspMap = NULL,
                         *pLspMapEntryDel = NULL;
    DWORD               *pdwCatalogOrder = NULL;
    INT                  iProviderCount = 0,
                         iLayerCount = 0,
                         iLspCount = 0,
                         ErrorCode,
                         Status,
                         rc,
                         i, j, k, l;

    Status = SOCKET_ERROR;

    // Enumerate the catalog
    pProvider = EnumerateProviders( Catalog, &iProviderCount );
    if ( pProvider == NULL )
    {
        fprintf( stderr, "RemoveProvider: Unable to enumerate catalog!\n" );
        goto cleanup;
    }

    // Allocate an array to save of the provider order in case we have to
    //    do uninstall and reinstall providers
    pdwCatalogOrder = (DWORD *) LspAlloc(
                          sizeof( DWORD ) * iProviderCount,
                          &ErrorCode
                      );
    if ( NULL == pdwCatalogOrder )
    {
        fprintf( stderr, "RemoveProvider: LspAlloc failed: %d\n", ErrorCode );
        goto cleanup;
    }

    for(i=0; i < iProviderCount ; i++)
    {
        pdwCatalogOrder[ i ] = pProvider[ i ].dwCatalogEntryId;
    }

    // Build a map of the LSPs installed on the system
    pLspMap = BuildLspMap( pProvider, iProviderCount, &iLspCount );
    if ( NULL == pLspMap )
    {
        fprintf( stderr, "RemoveProvider: Unable to build LSP map!\n" );
        goto cleanup;
    }

    // Validate the catalog entry ID to remove
    pLspMapEntryDel = NULL;

    for(i=0; ( i < iLspCount ) && ( NULL == pLspMapEntryDel ) ; i++)
    {
        if ( dwProviderId == pLspMap[ i ].DummyEntry.dwCatalogEntryId )
        {
            pLspMapEntryDel = &pLspMap[ i ];
        }
        else
        {
            for(j=0; j < pLspMap[ i ].Count ; j++)
            {
                if ( dwProviderId == pLspMap[ i ].LayeredEntries[ j ].dwCatalogEntryId )
                {
                    // In this case the user supplied the catalog ID of an LSP protocol
                    // chain entry -- not the hidden layered entry (dummy). Here we'll
                    // reset the dwProviderId to that of the dummy hidden entry.
                    //
                    if ( pLspMap[ i ].OrphanedEntries != TRUE )
                    {
                        printf( "Catalog ID %d is a layered protocol entry and not the hidden\n"
                                "provider representing the entire LSP. The LSP which owns this\n"
                                "provider is ID %d (%ws). This entire LSP will be removed!\n",
                                dwProviderId,
                                pLspMap[ i ].DummyEntry.dwCatalogEntryId,
                                pLspMap[ i ].DummyEntry.szProtocol
                              );
                        dwProviderId = pLspMap[ i ].DummyEntry.dwCatalogEntryId;
                        pLspMapEntryDel = &pLspMap[ i ];
                    }
                    else
                    {
                        printf( "Catalog ID %d is one of %d orphaned protocol entries.\n"
                                "These entries could be causing serious problems and\n"
                                "will be removed. The following providers are to be\n"
                                "deleted:\n",
                                pLspMap[ i ].LayeredEntries[ j ].dwCatalogEntryId,
                                pLspMap[ i ].Count
                              );
                        for(k=0; k < pLspMap[ i ].Count ; k++)
                        {
                            printf("   %d: %ws\n",
                                   pLspMap[ i ].LayeredEntries[ k ].dwCatalogEntryId,
                                   pLspMap[ i ].LayeredEntries[ k ].szProtocol
                                  );
                        }
                        pLspMapEntryDel = &pLspMap[ i ];
                    }
                    break;
                }
            }
        }
    }

    // Make sure we found a provider to remove
    if ( NULL == pLspMapEntryDel )
    {
        fprintf( stderr, "\n\nError! Invalid Winsock catalog ID supplied: %d\n",
                 dwProviderId
               );
        goto cleanup;
    }

    //
    // Print which entries are being removed
    //

    printf( "\nThe following LSP entries will be removed:\n" );
    if ( pLspMapEntryDel->OrphanedEntries != TRUE )
    {
        printf( "LSP Hidden ID: %6d Name %ws\n",
                pLspMapEntryDel->DummyEntry.dwCatalogEntryId,
                pLspMapEntryDel->DummyEntry.szProtocol
              );
    }
    else
    {
        printf( "Orphaned LSP protocol chain entries:\n");
    }
    for(i=0; i < pLspMapEntryDel->Count ; i++)
    {
        printf( "LSP Layer  ID: %6d Name %ws\n",
                pLspMapEntryDel->LayeredEntries[ i ].dwCatalogEntryId,
                pLspMapEntryDel->LayeredEntries[ i ].szProtocol
              );
    }

    ErrorCode = NO_ERROR;

    if ( 0 != pLspMapEntryDel->DependentCount )
    {
        int iLspIdx;

        printf( "\n\nOther LSPs are dependent on this one! "
                "Additional cleanup is required..\n\n" );

        for(i=0; i < pLspMapEntryDel->DependentCount ; i++)
        {
            iLspIdx =  pLspMapEntryDel->DependentLspIndexArray[ i ];

            printf( "Fixing LSP index %d: %ws\n",
                    pLspMap[ iLspIdx ].DummyEntry.dwCatalogEntryId,
                    pLspMap[ iLspIdx ].DummyEntry.szProtocol
                  );

            // Remove any reference to the deleted LSPs dummy catalog ID
            for(j=0; j < pLspMap[ iLspIdx ].Count ; j++)
            {
                if ( IsIdInChain( &pLspMap[ iLspIdx ].LayeredEntries[ j ],
                                  pLspMapEntryDel->DummyEntry.dwCatalogEntryId )
                   )
                {
                    printf( "Removing ID %d from layered chain %d: %ws\n",
                            pLspMapEntryDel->DummyEntry.dwCatalogEntryId,
                            pLspMap[ iLspIdx ].LayeredEntries[ j ].dwCatalogEntryId,
                            pLspMap[ iLspIdx ].LayeredEntries[ j ].szProtocol
                          );

                    // Remove the deleted LSPs ID from the chain
                    rc = RemoveIdFromChain(
                             &pLspMap[ iLspIdx ].LayeredEntries[ j ],
                             pLspMapEntryDel->DummyEntry.dwCatalogEntryId
                         );
                    if ( FALSE == rc )
                    {
                        fprintf( stderr, "RemoveProvider: ID not found in chain!\n" );
                        continue;
                    }

                    pLspMap[ iLspIdx ].LayerChanged[ j ] = TRUE;
                }
            }

            // Remove any reference to the deleted LSPs layered entries catalog
            // IDs from the layers of the dependent LSP
            for(l=0; l < pLspMapEntryDel->Count ; l++)
            {
                for(j=0; j < pLspMap[ iLspIdx ].Count ; j++)
                {
                    if ( IsIdInChain( &pLspMap[ iLspIdx ].LayeredEntries[ j ],
                                      pLspMapEntryDel->LayeredEntries[ l ].dwCatalogEntryId )
                       )
                    {
                        printf( "Removing ID %d from layered chain %d: %ws\n",
                                pLspMapEntryDel->DummyEntry.dwCatalogEntryId,
                                pLspMap[ iLspIdx ].LayeredEntries[ j ].dwCatalogEntryId,
                                pLspMap[ iLspIdx ].LayeredEntries[ j ].szProtocol
                              );

                        // Remove the deleted LSPs ID from the chain
                        rc = RemoveIdFromChain(
                                 &pLspMap[ iLspIdx ].LayeredEntries[ j ],
                                 pLspMapEntryDel->LayeredEntries[ l ].dwCatalogEntryId
                             );
                        if ( FALSE == rc )
                        {
                            fprintf( stderr, "RemoveProvider: ID not found in chain!\n" );
                            continue;
                        }

                        pLspMap[ iLspIdx ].LayerChanged[ j ] = TRUE;
                    }
                }
            }
        }

        //
        // All dependent LSPs should no longer reference any of the LSPs IDs which is
        //    to be removed. Now we must write our changes back to the catalog. Life
        //    is easy if we're on a system that supports WSCUpdateProvider.
        //

        if ( NULL != fnWscUpdateProvider )
        {
            //
            // Life is good, simply call UpdateProvider on each entry in the LSP map
            //    that was updated.
            //
            for(i=0; i < pLspMapEntryDel->DependentCount ; i++)
            {
                iLspIdx = pLspMapEntryDel->DependentLspIndexArray[ i ];

                for(j=0; j < pLspMap[ iLspIdx ].Count; j++)
                {
                    if ( TRUE == pLspMap[ iLspIdx ].LayerChanged[ j ] )
                    {
                        rc = UpdateProvider(
                                 Catalog,
                                 &pLspMap[ iLspIdx ].LayeredEntries[ j ].ProviderId,
                                 pLspMap[ iLspIdx ].wszLspDll,
                                 &pLspMap[ iLspIdx ].LayeredEntries[ j ],
                                 1,
                                 &ErrorCode
                             );
                    }
                }
            }
        }
        else        // fnWscUpdateProvider == NULL
        {
            int                 MaxLayers = 0;

            //
            // Life isn't so good. We need to remove all dependent LSPs first in the
            //    reverse order they were installed so that if something fails, we
            //    won't leave the catalog in a bad state. Then we need to reinstall
            //    them in the same order they were originally installed and fix any
            //    of the remaining dependent LSPs to reference the correct catalog IDs
            //    before they are also reinstalled.
            //

            // Find the maximum protocol chain length of all the LSPs since we need
            //    scratch space. We do the allocation first before making changes to
            //    the catalog.
            MaxLayers = MaxLayeredChainCount(
                            pLspMap,
                            iLspCount
                        );

            pLayeredEntries = (WSAPROTOCOL_INFOW *) LspAlloc(
                                  sizeof( WSAPROTOCOL_INFOW ) * MaxLayers,
                                  &ErrorCode
                              );
            if ( NULL == pLayeredEntries )
            {
                fprintf( stderr, "RemoveProvider: LspAlloc failed: %d\n",
                         ErrorCode );
                goto cleanup;
            }

            // Remove the dependent LSPs in reverse order. NOTE: We don't have to
            //    remove the dummy hidden entries since there is no information
            //    in those providers that need updating.
            for(i=0; i < pLspMapEntryDel->DependentCount ; i++)
            {
                iLspIdx = pLspMapEntryDel->DependentLspIndexArray[ i ];

                for(j=0; j < pLspMap[ iLspIdx ].LayeredGuidCount ; j++)
                {
                    rc = DeinstallProvider(
                             Catalog,
                             &pLspMap[ iLspIdx ].LayeredGuids[ j ]
                         );
                    if ( SOCKET_ERROR == rc )
                    {
                        fprintf( stderr,
                                 "RemoveProvider: An error occured trying to remove an LSP.\n"
                                 "\t\tThis may be due to another process changing the Catalog\n"
                                 "\t\tAborting...\n"
                               );
                        goto cleanup;
                    }
                }
            }

            // All the dependent LSP layers have been removed, now add them
            // back in reverse order
            for(i=pLspMapEntryDel->DependentCount-1; i >= 0 ; i--)
            {
                iLspIdx = pLspMapEntryDel->DependentLspIndexArray[ i ];

                // Install the layered entries
                for(j=0; j < pLspMap[ iLspIdx ].LayeredGuidCount ; j++)
                {
                    iLayerCount = MaxLayers;

                    rc = GetLayeredEntriesByGuid(
                             pLayeredEntries,
                             &iLayerCount,
                             pLspMap[ iLspIdx ].LayeredEntries,
                             pLspMap[ iLspIdx ].Count,
                             &pLspMap[ iLspIdx ].LayeredGuids[ j ]
                         );

                    rc = InstallProvider(
                             Catalog,
                             &pLspMap[ iLspIdx ].LayeredGuids[ j ],
                             pLspMap[ iLspIdx ].wszLspDll,
                             pLayeredEntries,
                             iLayerCount
                         );

                }

                // Enumerate catalog to find new IDs

                DWORD ProviderLen = iProviderCount * sizeof( WSAPROTOCOL_INFOW );

                int NewProviderCount = EnumerateProvidersExisting(
                                           Catalog,
                                           pProvider,
                                           &ProviderLen
                                       );
                if ( SOCKET_ERROR == NewProviderCount )
                {
                    fprintf( stderr, "RemoveProvider: EnumerateProvidersExisting failed: %d\n",
                             GetLastError() );
                }

                // Update the old references to the new
                MapNewEntriesToOld(
                    &pLspMap[ iLspIdx ],
                    pProvider,
                    NewProviderCount
                );

                // Update the provider order array with the new provider values
                UpdateProviderOrder(
                    &pLspMap[ iLspIdx ],
                    pdwCatalogOrder,
                    iProviderCount
                );

                // For the remaining LSPs which we still need to install, update any
                //    references to the removed LSPs with their new IDs
                for(k=i-1; k >= 0 ; k--)
                {
                    int iLspIdx2 = pLspMapEntryDel->DependentLspIndexArray[ k ];

                    printf( "Updating IDs for index %d\n", iLspIdx2 );

                    for(l=0; l < pLspMap[ iLspIdx ].Count ; l++)
                    {
                        UpdateLspMap(
                            &pLspMap[ iLspIdx2 ],
                            pLspMap[ iLspIdx ].LayeredEntries[ l ].dwCatalogEntryId,
                            pLspMap[ iLspIdx ].LayeredEntries[ l ].dwProviderReserved
                        );
                    }
                }
            }

            // Reorder the catalog back to what it was before. Since we've added
            //    back all the LSPs we removed earlier, the catalog should be the
            //    same size as when we started.
            rc = WriteProviderOrder(
                     Catalog,
                     pdwCatalogOrder,
                     iProviderCount,
                     &ErrorCode
                 );
            if ( SOCKET_ERROR == rc )
            {
                fprintf( stderr, "RemoveProvider: WriteProviderOrder failed: %d\n",
                         ErrorCode );
            }
        }
    }

    //
    // Now all dependencies have been fixed, remove the specified provider
    //

    // Remove the layered protocol entries
    for(i=0; i < pLspMapEntryDel->LayeredGuidCount ; i++)
    {
        rc = DeinstallProvider(
                 Catalog,
                 &pLspMapEntryDel->LayeredGuids[ i ]
             );
    }

    // Remove the dummy entry
    rc = DeinstallProvider(
             Catalog,
             &pLspMapEntryDel->DummyEntry.ProviderId
         );

    Status = NO_ERROR;

cleanup:

    //
    // Cleanup allocations
    //

    if ( NULL != pLayeredEntries )
        LspFree( pLayeredEntries );

    if ( NULL != pProvider )
        FreeProviders(pProvider);

    if ( NULL != pLspMap )
        FreeLspMap( pLspMap, iLspCount );

    if ( NULL != pdwCatalogOrder )
        LspFree( pdwCatalogOrder );

    return Status;
}