/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) 1997-1999, Microsoft Corporation **/ /**********************************************************************/ /* ndisutil.cpp FILE HISTORY: */ #include "stdafx.h" #include "ndisutil.h" #include "rtrstr.h" #include "raserror.h" #include "ustringp.h" #include #include #include "ncutil.h" #include #define c_szDevice L"\\Device\\" #define c_szEmpty L"" //------------------------------------------------------------------- // Function: SetUnicodeString // // Purpose: given a UNICODE_STRING initialize it to the given WSTR // // Parameters: // pustr - the UNICODE_STRING to initialize // psz - the WSTR to use to initialize the UNICODE_STRING // // Notes: This differs from the RtlInitUnicodeString in that the // MaximumLength value contains the terminating null // //------------------------------------------------------------------- void SetUnicodeString ( IN OUT UNICODE_STRING* pustr, IN LPCWSTR psz ) { AssertSz( pustr != NULL, "Invalid Argument" ); AssertSz( psz != NULL, "Invalid Argument" ); pustr->Buffer = const_cast(psz); pustr->Length = (USHORT)(lstrlenW(pustr->Buffer) * sizeof(WCHAR)); pustr->MaximumLength = pustr->Length + sizeof(WCHAR); } //------------------------------------------------------------------- // Function: SetUnicodeMultiString // // Purpose: given a UNICODE_STRING initialize it to the given WSTR // multi string buffer // // Parameters: // pustr - the UNICODE_STRING to initialize // pmsz - the multi sz WSTR to use to initialize the UNICODE_STRING // //------------------------------------------------------------------- void SetUnicodeMultiString ( IN OUT UNICODE_STRING* pustr, IN LPCWSTR pmsz ) { AssertSz( pustr != NULL, "Invalid Argument" ); AssertSz( pmsz != NULL, "Invalid Argument" ); pustr->Buffer = const_cast(pmsz); // Note: Length does NOT include terminating NULL pustr->Length = wcslen(pustr->Buffer) * sizeof(WCHAR); pustr->MaximumLength = pustr->Length; } //------------------------------------------------------------------- // Function: HrSendNdisHandlePnpEvent // // Purpose: Send to Ndis a HandlePnpEvent notification // // Parameters: // uiLayer - either NDIS or TDI // uiOperation - either BIND, RECONFIGURE, or UNBIND // pszUpper - a WIDE string containing the upper component name // pszLower - a WIDE string containing the lower component name // This is one of the Export names from that component // The values NULL and c_szEmpty are both supported // pmszBindList - a WIDE string containing the NULL terminiated list of strings // representing the bindlist, vaid only for reconfigure // The values NULL and c_szEmpty are both supported // pvData - Pointer to ndis component notification data. Content // determined by each component. // dwSizeData - Count of bytes in pvData // // Returns: HRESULT S_OK on success, HrFromLastWin32Error otherwise // // Notes: Do not use this routine directly, see... // HrSendNdisPnpBindOrderChange, // HrSendNdisPnpBindStateChange, or // HrSendNdisPnpReconfig // //------------------------------------------------------------------- HRESULT HrSendNdisHandlePnpEvent ( UINT uiLayer, UINT uiOperation, LPCWSTR pszUpper, LPCWSTR pszLower, LPCWSTR pmszBindList, PVOID pvData, DWORD dwSizeData) { UNICODE_STRING umstrBindList; UNICODE_STRING ustrLower; UNICODE_STRING ustrUpper; UINT nRet; HRESULT hr = S_OK; Assert(NULL != pszUpper); Assert((NDIS == uiLayer)||(TDI == uiLayer)); Assert( (BIND == uiOperation) || (RECONFIGURE == uiOperation) || (UNBIND == uiOperation) ); // AssertSz( FImplies( ((NULL != pmszBindList) && (0 != lstrlenW( pmszBindList ))), // (RECONFIGURE == uiOperation) && // (TDI == uiLayer) && // (0 == lstrlenW( pszLower ))), // "bind order change requires a bind list, no lower, only for TDI, and with Reconfig for the operation" ); // optional strings must be sent as empty strings // if (NULL == pszLower) { pszLower = c_szEmpty; } if (NULL == pmszBindList) { pmszBindList = c_szEmpty; } // build UNICDOE_STRINGs SetUnicodeMultiString( &umstrBindList, pmszBindList ); SetUnicodeString( &ustrUpper, pszUpper ); SetUnicodeString( &ustrLower, pszLower ); // Now submit the notification nRet = NdisHandlePnPEvent( uiLayer, uiOperation, &ustrLower, &ustrUpper, &umstrBindList, (PVOID)pvData, dwSizeData ); if (!nRet) { hr = HRESULT_FROM_WIN32(GetLastError()); } // TraceError( "HrSendNdisHandlePnpEvent", hr ); return( hr ); } //------------------------------------------------------------------- // Function: HrSendNdisPnpReconfig // // Purpose: Send to Ndis a HandlePnpEvent reconfig notification // // Parameters: uiLayer - either NDIS or TDI // wszUpper - a WIDE string containing the upper component name // (typically a protocol) // wszLower - a WIDE string containing the lower component name // (typically an adapter bindname) The values NULL and // c_szEmpty are both supported // pvData - Pointer to ndis component notification data. Content // determined by each component. // dwSizeData - Count of bytes in pvData // // Returns: HRESULT S_OK on success, HrFromLastWin32Error otherwise // //------------------------------------------------------------------- HRESULT HrSendNdisPnpReconfig ( UINT uiLayer, LPCWSTR wszUpper, LPCWSTR wszLower, PVOID pvData, DWORD dwSizeData) { Assert(NULL != wszUpper); Assert((NDIS == uiLayer)||(TDI == uiLayer)); if (NULL == wszLower) { wszLower = c_szEmpty; } WCHAR* pLower = NULL; // tstring strLower; // If a lower component is specified, prefix with "\Device\" else // strLower's default of an empty string will be used. if ( wszLower && lstrlenW(wszLower)) { pLower = (WCHAR*)_alloca((lstrlenW(wszLower) + lstrlenW(c_szDevice) + 2) * sizeof(WCHAR)); wcscpy(pLower, c_szDevice); wcscat(pLower, wszLower); } HRESULT hr = HrSendNdisHandlePnpEvent( uiLayer, RECONFIGURE, wszUpper, pLower, c_szEmpty, pvData, dwSizeData); // TraceError( "HrSendNdisPnpReconfig", hr); return hr; }