Benutzer mit den meisten Antworten
Struct WLAN_RAW_DATA_LIST erzeugen

Frage
-
Hallo,
ich arbeite mich in C++ ein und verstehe nicht wie ich dieser Struct WLAN_RAW_DATA_LIST den DataBlob hinzufüge.
typedef struct _WLAN_RAW_DATA_LIST { DWORD dwTotalSize; DWORD dwNumberOfItems; struct { // the beginning of the data blob // the offset is w.r.t. the beginning of the entry DWORD dwDataOffset; // size of the data blob DWORD dwDataSize; } DataList[1]; } WLAN_RAW_DATA_LIST, *PWLAN_RAW_DATA_LIST;
Gruß Thomas
13 Millionen Schweine landen jährlich im Müll
Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings
Antworten
-
Ok jetzt verstehe ich wie dumm meine frage ist und wie wenig ich von C++ verstehe.
Man reserviert Arbeitsspeicher und schreibt den struct der die Größe und die Positionen den Daten angibt am Anfang des Datensatzes gefolgt von den Daten selbst. In C# wäre das ein einfaches byte[] wobei der type DWORD 4 bytes einnimmt. In C++ macht das sicherlich sinn da man dann nur einen reservierten Bereich hat den man wieder freigeben muss. Ist eigentlich nicht anderes als ein protokolierten Stream zu lesen. Hätte ich auch früher drauf kommen können
Gruß Thomas
13 Millionen Schweine landen jährlich im Müll
Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings- Als Antwort vorgeschlagen Florian Haupt Freitag, 2. August 2019 06:54
- Als Antwort markiert Thomas Wycichowski Freitag, 2. August 2019 14:31
-
Hallo Thomas,
da hier im Forum Antworten vom Wochenende verlorengingen, poste ich nochmal den Code. Den Text habe ich nicht mehr, den hattest du ja schon zur Kenntnis genommen.
DWORD SetIe(HANDLE hClient) { DWORD dwResult = 0; PWLAN_RAW_DATA_LIST rawDataList = new WLAN_RAW_DATA_LIST(); LPCWSTR formatData = L"http://schemas.xmlsoaps.org/ws/2004/10/discovery"; char ieData[] = { '\x00', '\x01', '\x02', '\x03' }; rawDataList->dwTotalSize = 16 + sizeof(ieData); rawDataList->dwNumberOfItems = 1; rawDataList->DataList[0].dwDataOffset = 8; rawDataList->DataList[0].dwDataSize = sizeof(ieData); char* buffer = new char[rawDataList->dwTotalSize]; // sizeof(&rawDataList) oder sizeof(rawDataList) würden nur 4 (bzw. 8 auf 64-Bit-OS) ergeben, da dies Zeiger sind. // memcpy(&buffer, &rawDataList, sizeof(&rawDataList)); memcpy(buffer, rawDataList, sizeof(WLAN_RAW_DATA_LIST)); for (size_t i = 0, j = 16; i < sizeof(ieData); i++, j++) { buffer[j] = ieData[i]; } // 'rawDataList' und 'buffer' sollten keine weitere Zuweisung erhalten, da ihr // speicher wieder freigegeben werden muß. // rawDataList = (PWLAN_RAW_DATA_LIST)buffer; DWORD ret = WlanSetPsdIEDataList(hClient, formatData, (PWLAN_RAW_DATA_LIST)buffer, NULL); delete []buffer; delete rawDataList; // return WlanSetPsdIEDataList(hClient, formatData, rawDataList, NULL); return ret; }
// WifiDirect.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include <windows.h> #include <wlanapi.h> struct BLOB_HEADER { DWORD dwOffset, dwSize; }; struct PSD { BYTE Id; BYTE Length; BYTE OUI[3]; BYTE OUIType; BYTE FormatIdentifierHash[4]; BYTE Data[230]; // Maximale Länge; Data kann kürzer sein. }; int _tmain(int argc, _TCHAR* argv[]); DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int size, BYTE * data); DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize1, BYTE * data1, int dataSize2, BYTE * data2, int dataSize3, BYTE * data3, int dataSize4, BYTE * data4, int dataSize5, BYTE * data5); void PrintResult(DWORD error); int _tmain(int argc, _TCHAR* argv[]) { DWORD ret, usedVersion; HANDLE hWlan; ret = WlanOpenHandle(2, NULL, &usedVersion, &hWlan); if (ret != ERROR_SUCCESS) { PrintResult(ret); return -1; } // Siehe https://docs.microsoft.com/de-de/windows/win32/api/wlanapi/nf-wlanapi-wlansetpsdiedatalist int size = sizeof(PSD); wchar_t * format = L"http://schemas.xmlsoaps.org/ws/2004/10/discovery"; PSD * pPsd = new PSD; memset(pPsd, 0, sizeof(PSD)); pPsd->Id = 221; pPsd->Length = 10; // 8; Die Länge soll PSD.Data + 8 sein. Die Felder in PSD vor PSD.Data sind jedoch 10 Bytes. ??? pPsd->OUI[0] = (BYTE)0x00; pPsd->OUI[1] = (BYTE)0x50; pPsd->OUI[2] = (BYTE)0xF2; pPsd->OUIType = 6; pPsd->FormatIdentifierHash[0] = 0xF8; pPsd->FormatIdentifierHash[1] = 0xCB; pPsd->FormatIdentifierHash[2] = 0x35; pPsd->FormatIdentifierHash[3] = 0x15; //BYTE data[] = { (BYTE)0x00, (BYTE)0x01, (BYTE)0x02, (BYTE)0x03 }; //size = sizeof(data); //ret = SetBlobs(hWlan, format, size, data); ret = SetBlobs(hWlan, format, size, (BYTE *)pPsd); if (ret == ERROR_SUCCESS) { // Test mit mehreren Blobs (bis zu 5; DOT11_PSD_IE_MAX_ENTRY_NUMBER) PSD psd2, psd3, psd4; memcpy(&psd2, pPsd, size); memcpy(&psd3, pPsd, size); memcpy(&psd4, pPsd, size); // ERROR_SUCCESS // ret = SetBlobs(hWlan, format, size, data, size, data, 0, NULL, 0, NULL, 0, NULL); // ret = SetBlobs(hWlan, format, size, (BYTE *)&psd2, 0, NULL, 0, NULL, 0, NULL, 0, NULL); ret = SetBlobs(hWlan, format, size, (BYTE *)pPsd, size, (BYTE *)&psd2, size, (BYTE *)&psd3, size, (BYTE *)&psd4, 0, NULL); } delete pPsd; WlanCloseHandle(hWlan, NULL); PrintResult(ret); return 0; } // Für genau einen Blob. DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize, BYTE * data) { // Ohne Blobs liefert WlanSetPsdIEDataList() auch ERROR_SUCCESS. /* WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[8]; pList->dwTotalSize = 8; pList->dwNumberOfItems = 0; DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); PrintResult(ret); delete[](BYTE *)pList; return ret; */ if (!hWlan || dataSize <= 0 || dataSize > DOT11_PSD_IE_MAX_DATA_SIZE || !data) return ERROR_INVALID_PARAMETER; int size = sizeof(WLAN_RAW_DATA_LIST) + dataSize; WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[size]; pList->dwTotalSize = size; // Die Angabe im Beispiel der MSDN ist widersprüchlich, statt 84 sollte dort 68 (nach meiner Meinung) stehen. pList->dwNumberOfItems = 1; pList->DataList[0].dwDataSize = dataSize; pList->DataList[0].dwDataOffset = 8; memcpy((BYTE *)pList + sizeof(WLAN_RAW_DATA_LIST), data, dataSize); DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); delete [](BYTE *)pList; return ret; } // Für 0 bis 5 Blobs. DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize1, BYTE * data1, int dataSize2, BYTE * data2, int dataSize3, BYTE * data3, int dataSize4, BYTE * data4, int dataSize5, BYTE * data5) { if (!hWlan) return ERROR_INVALID_PARAMETER; DWORD size = sizeof(BLOB_HEADER), dataOffset = 0, count = 0; if (dataSize1 < 0 || dataSize1 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize1 > 0 && !data1) return ERROR_INVALID_PARAMETER; else if (dataSize1 > 0) { size += sizeof(BLOB_HEADER) + dataSize1; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize2 < 0 || dataSize2 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize2 > 0 && !data2) return ERROR_INVALID_PARAMETER; else if (dataSize2 > 0) { size += sizeof(BLOB_HEADER) + dataSize2; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize3 < 0 || dataSize3 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize3 > 0 && !data3) return ERROR_INVALID_PARAMETER; else if (dataSize3 > 0) { size += sizeof(BLOB_HEADER) + dataSize3; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize4 < 0 || dataSize4 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize4 > 0 && !data4) return ERROR_INVALID_PARAMETER; else if (dataSize4 > 0) { size += sizeof(BLOB_HEADER) + dataSize4; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize5 < 0 || dataSize5 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize5 > 0 && !data5) return ERROR_INVALID_PARAMETER; else if (dataSize5 > 0) { size += sizeof(BLOB_HEADER) + dataSize5; dataOffset += sizeof(BLOB_HEADER); count++; } } } } } WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[size]; pList->dwTotalSize = size; pList->dwNumberOfItems = count; BLOB_HEADER * pBlobHeader = (BLOB_HEADER *)&pList->DataList; BYTE * pData = (BYTE *)&pList->DataList + dataOffset; if (count >= 1) { pBlobHeader->dwSize = dataSize1; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data1, dataSize1); if (count >= 2) { pBlobHeader++; pData += dataSize1; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize1; pBlobHeader->dwSize = dataSize2; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data2, dataSize2); if (count >= 3) { pBlobHeader++; pData += dataSize2; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize2; pBlobHeader->dwSize = dataSize3; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data3, dataSize3); if (count >= 4) { pBlobHeader++; pData += dataSize3; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize3; pBlobHeader->dwSize = dataSize4; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data4, dataSize4); if (count >= 5) { pBlobHeader++; pData += dataSize4; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize4; pBlobHeader->dwSize = dataSize5; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data5, dataSize5); } } } } } DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); // Da der Speicher für 'pList' als Array (von BYTEs) angefordert wurde, muß er auch als Array freigegeben werden. delete[](BYTE *)pList; return ret; } void PrintResult(DWORD error) { switch (error) { case ERROR_SUCCESS: puts("ERROR_SUCCESS"); break; case ERROR_INVALID_PARAMETER: puts("ERROR_INVALID_PARAMETER"); break; case ERROR_NOT_ENOUGH_MEMORY: puts("ERROR_NOT_ENOUGH_MEMORY"); break; case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: puts("ERROR_REMOTE_SESSION_LIMIT_EXCEEDED"); break; default: printf("0x%08X\r\n", error); break; } getchar(); }
Gruß,
Heiko- Als Antwort markiert Thomas Wycichowski Dienstag, 20. August 2019 15:54
- Tag als Antwort aufgehoben Thomas Wycichowski Dienstag, 20. August 2019 17:18
- Als Antwort markiert Thomas Wycichowski Dienstag, 20. August 2019 20:37
-
Hallo Thomas,
dumme Fragen gibt es nicht. Man wird doch wohl untereinander laut denken dürfen ;-)
Im C++ Code bringst du einiges durcheinander. Ein memcpy() mit den Adressen von Zeigervariablen (also Zeiger auf Zeiger) ist wie eine normale Zuweisung einer Zeigervariablen mit =, die hier mit memcpy() sicher nicht gewollt ist. Dass das Beispiel nicht abstürzt, ist wohl eher Zufall ;-)
Im C++ sollte man immer an das delete denken. Dabei kommt es darauf an, ob ein Array oder ein einzelner Typ beim new angegeben wurde. Je nachdem ist 'delete' oder 'delete []' zu verwenden.
Die Struktur WLAN_RAW_DATA_LIST enthält keine Zeiger. Deshalb sollte man auch nicht beim Versuch, die Struktur im C# nachzubilden, einen Zeiger einbauen. Die Struktur enthält Daten, die im Speicher zusammenhängend sind. Da die Struktur eine dynamische Länge haben kann, muß man vorher die Größe des zu benötigten Speichers berechnen.
Sollte eine Struktur nicht nur aus DWORDs bestehen, sondern auch BYTEs und größere Typen gemischt beinhalten, muß man das Alignment beachten. Dadurch kann theoretisch sizeof(MY_STRUCT) größer sein, als die Summe ihrer Member. Das Alignment sollte man jedoch nicht ändern, besonders, wenn Strukturen Modul-übergreifend verwendet werden. (Siehe Projekt-Einstellungen/C++/Codegenerierung/Strukturmemberausrichtung) Bei WLAN_RAW_DATA_LIST spielt das Alignment keine Rolle, da hier nur DWORDs verwendet werden und durch das Alignment keine Lücken in der Struktur entstehen können.
Das Beispiel in der MSDN zu WLAN_RAW_DATA_LIST enthält in dwTotalSize 84. Das ist verwirrend, da meiner Meinung nach die resultierende Größe 68 ergibt.
Bei der Beschreibung der PSD-Struktur wird gesagt, dass die Length = (Länge der Daten + 8) sein soll. Die PSD-Header-Angaben nehmen jedoch 10 Bytes ein. => ebenfalls komisch.
Ich habe mal versucht, das Ganze nachzustellen. Auch mit mehreren PSD-Strukturen, also mit mehreren Blobs, funktioniert es, ERROR_SUCCESS.
In C# müßte man wohl alle Felder nach und nach in eine List<byte> einfügen. Dabei könnte man für die DWORDs folgendes verwenden:
uint totalSize = x; byteList.AddRange(BitConverter.GetBytes(totalSize));
Den Zeiger auf ein Array von byteList.ToArray() würde man dann an WlanSetPsdIEDataList() übergeben.
Ich hoffe, ich kann dir mit dem C++ etwas hilfreich sein und du bekommst wieder Lust am Projekt.
// WifiDirect.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include <windows.h> #include <wlanapi.h> struct BLOB_HEADER { DWORD dwOffset, dwSize; }; struct PSD { BYTE Id; BYTE Length; BYTE OUI[3]; BYTE OUIType; BYTE FormatIdentifierHash[4]; BYTE Data[230]; // Maximale Länge; Data kann kürzer sein. }; int _tmain(int argc, _TCHAR* argv[]); DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int size, BYTE * data); DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize1, BYTE * data1, int dataSize2, BYTE * data2, int dataSize3, BYTE * data3, int dataSize4, BYTE * data4, int dataSize5, BYTE * data5); void PrintResult(DWORD error); int _tmain(int argc, _TCHAR* argv[]) { DWORD ret, usedVersion; HANDLE hWlan; ret = WlanOpenHandle(2, NULL, &usedVersion, &hWlan); if (ret != ERROR_SUCCESS) { PrintResult(ret); return -1; } // Siehe https://docs.microsoft.com/de-de/windows/win32/api/wlanapi/nf-wlanapi-wlansetpsdiedatalist int size = sizeof(PSD); wchar_t * format = L"http://schemas.xmlsoaps.org/ws/2004/10/discovery"; PSD * pPsd = new PSD; memset(pPsd, 0, sizeof(PSD)); pPsd->Id = 221; pPsd->Length = 10; // 8; Die Länge soll PSD.Data + 8 sein. Die Felder in PSD vor PSD.Data sind jedoch 10 Bytes. ??? pPsd->OUI[0] = (BYTE)0x00; pPsd->OUI[1] = (BYTE)0x50; pPsd->OUI[2] = (BYTE)0xF2; pPsd->OUIType = 6; pPsd->FormatIdentifierHash[0] = 0xF8; pPsd->FormatIdentifierHash[1] = 0xCB; pPsd->FormatIdentifierHash[2] = 0x35; pPsd->FormatIdentifierHash[3] = 0x15; //BYTE data[] = { (BYTE)0x00, (BYTE)0x01, (BYTE)0x02, (BYTE)0x03 }; //size = sizeof(data); //ret = SetBlobs(hWlan, format, size, data); ret = SetBlobs(hWlan, format, size, (BYTE *)pPsd); if (ret == ERROR_SUCCESS) { // Test mit mehreren Blobs (bis zu 5; DOT11_PSD_IE_MAX_ENTRY_NUMBER) PSD psd2, psd3, psd4; memcpy(&psd2, pPsd, size); memcpy(&psd3, pPsd, size); memcpy(&psd4, pPsd, size); // ERROR_SUCCESS // ret = SetBlobs(hWlan, format, size, data, size, data, 0, NULL, 0, NULL, 0, NULL); // ret = SetBlobs(hWlan, format, size, (BYTE *)&psd2, 0, NULL, 0, NULL, 0, NULL, 0, NULL); ret = SetBlobs(hWlan, format, size, (BYTE *)pPsd, size, (BYTE *)&psd2, size, (BYTE *)&psd3, size, (BYTE *)&psd4, 0, NULL); } delete pPsd; WlanCloseHandle(hWlan, NULL); PrintResult(ret); return 0; } // Für genau einen Blob. DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize, BYTE * data) { // Ohne Blobs liefert WlanSetPsdIEDataList() auch ERROR_SUCCESS. /* WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[8]; pList->dwTotalSize = 8; pList->dwNumberOfItems = 0; DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); PrintResult(ret); delete[](BYTE *)pList; return ret; */ if (!hWlan || dataSize <= 0 || dataSize > DOT11_PSD_IE_MAX_DATA_SIZE || !data) return ERROR_INVALID_PARAMETER; int size = sizeof(WLAN_RAW_DATA_LIST) + dataSize; WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[size]; pList->dwTotalSize = size; // Die Angabe im Beispiel der MSDN ist widersprüchlich, statt 84 sollte dort 68 (nach meiner Meinung) stehen. pList->dwNumberOfItems = 1; pList->DataList[0].dwDataSize = dataSize; pList->DataList[0].dwDataOffset = 8; memcpy((BYTE *)pList + sizeof(WLAN_RAW_DATA_LIST), data, dataSize); DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); delete [](BYTE *)pList; return ret; } // Für 0 bis 5 Blobs. DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize1, BYTE * data1, int dataSize2, BYTE * data2, int dataSize3, BYTE * data3, int dataSize4, BYTE * data4, int dataSize5, BYTE * data5) { if (!hWlan) return ERROR_INVALID_PARAMETER; DWORD size = sizeof(BLOB_HEADER), dataOffset = 0, count = 0; if (dataSize1 < 0 || dataSize1 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize1 > 0 && !data1) return ERROR_INVALID_PARAMETER; else if (dataSize1 > 0) { size += sizeof(BLOB_HEADER) + dataSize1; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize2 < 0 || dataSize2 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize2 > 0 && !data2) return ERROR_INVALID_PARAMETER; else if (dataSize2 > 0) { size += sizeof(BLOB_HEADER) + dataSize2; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize3 < 0 || dataSize3 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize3 > 0 && !data3) return ERROR_INVALID_PARAMETER; else if (dataSize3 > 0) { size += sizeof(BLOB_HEADER) + dataSize3; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize4 < 0 || dataSize4 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize4 > 0 && !data4) return ERROR_INVALID_PARAMETER; else if (dataSize4 > 0) { size += sizeof(BLOB_HEADER) + dataSize4; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize5 < 0 || dataSize5 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize5 > 0 && !data5) return ERROR_INVALID_PARAMETER; else if (dataSize5 > 0) { size += sizeof(BLOB_HEADER) + dataSize5; dataOffset += sizeof(BLOB_HEADER); count++; } } } } } WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[size]; pList->dwTotalSize = size; pList->dwNumberOfItems = count; BLOB_HEADER * pBlobHeader = (BLOB_HEADER *)&pList->DataList; BYTE * pData = (BYTE *)&pList->DataList + dataOffset; if (count >= 1) { pBlobHeader->dwSize = dataSize1; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data1, dataSize1); if (count >= 2) { pBlobHeader++; pData += dataSize1; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize1; pBlobHeader->dwSize = dataSize2; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data2, dataSize2); if (count >= 3) { pBlobHeader++; pData += dataSize2; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize2; pBlobHeader->dwSize = dataSize3; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data3, dataSize3); if (count >= 4) { pBlobHeader++; pData += dataSize3; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize3; pBlobHeader->dwSize = dataSize4; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data4, dataSize4); if (count >= 5) { pBlobHeader++; pData += dataSize4; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize4; pBlobHeader->dwSize = dataSize5; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data5, dataSize5); } } } } } DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); // Da der Speicher für 'pList' als Array (von BYTEs) angefordert wurde, muß er auch als Array freigegeben werden. delete[](BYTE *)pList; return ret; } void PrintResult(DWORD error) { switch (error) { case ERROR_SUCCESS: puts("ERROR_SUCCESS"); break; case ERROR_INVALID_PARAMETER: puts("ERROR_INVALID_PARAMETER"); break; case ERROR_NOT_ENOUGH_MEMORY: puts("ERROR_NOT_ENOUGH_MEMORY"); break; case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: puts("ERROR_REMOTE_SESSION_LIMIT_EXCEEDED"); break; default: printf("0x%08X\r\n", error); break; } getchar(); }
Gruß,
Heiko
- Als Antwort markiert Thomas Wycichowski Samstag, 17. August 2019 17:15
- Bearbeitet Heiko65456465 Samstag, 17. August 2019 18:17 Korrektur im Code
-
Hallo Thomas,
in deinem Beispiel schreibst du Speicher kaputt, ohne dass es auffällt. Besser wäre es so:
DWORD SetIe(HANDLE hClient) { DWORD dwResult = 0; PWLAN_RAW_DATA_LIST rawDataList = new WLAN_RAW_DATA_LIST(); LPCWSTR formatData = L"http://schemas.xmlsoaps.org/ws/2004/10/discovery"; char ieData[] = { '\x00', '\x01', '\x02', '\x03' }; rawDataList->dwTotalSize = 16 + sizeof(ieData); rawDataList->dwNumberOfItems = 1; rawDataList->DataList[0].dwDataOffset = 8; rawDataList->DataList[0].dwDataSize = sizeof(ieData); char* buffer = new char[rawDataList->dwTotalSize]; // sizeof(&rawDataList) oder sizeof(rawDataList) würden nur 4 (bzw. 8 auf 64-Bit-OS) ergeben, da dies Zeiger sind. // memcpy(&buffer, &rawDataList, sizeof(&rawDataList)); memcpy(buffer, rawDataList, sizeof(WLAN_RAW_DATA_LIST)); for (size_t i = 0, j = 16; i < sizeof(ieData); i++, j++) { buffer[j] = ieData[i]; } // 'rawDataList' und 'buffer' sollten keine weitere Zuweisung erhalten, da ihr // Speicher wieder freigegeben werden muß. // rawDataList = (PWLAN_RAW_DATA_LIST)buffer; DWORD ret = WlanSetPsdIEDataList(hClient, formatData, (PWLAN_RAW_DATA_LIST)buffer, NULL); delete []buffer; delete rawDataList; // return WlanSetPsdIEDataList(hClient, formatData, rawDataList, NULL); return ret; }
Es ist jedoch nicht nötig, zwei mal Speicher anzufordern und zu kopieren, siehe dazu meine andere Antwort.
Gruß,
Heiko
- Bearbeitet Heiko65456465 Samstag, 17. August 2019 13:50
- Als Antwort markiert Thomas Wycichowski Samstag, 17. August 2019 17:15
Alle Antworten
-
Ok jetzt verstehe ich wie dumm meine frage ist und wie wenig ich von C++ verstehe.
Man reserviert Arbeitsspeicher und schreibt den struct der die Größe und die Positionen den Daten angibt am Anfang des Datensatzes gefolgt von den Daten selbst. In C# wäre das ein einfaches byte[] wobei der type DWORD 4 bytes einnimmt. In C++ macht das sicherlich sinn da man dann nur einen reservierten Bereich hat den man wieder freigeben muss. Ist eigentlich nicht anderes als ein protokolierten Stream zu lesen. Hätte ich auch früher drauf kommen können
Gruß Thomas
13 Millionen Schweine landen jährlich im Müll
Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings- Als Antwort vorgeschlagen Florian Haupt Freitag, 2. August 2019 06:54
- Als Antwort markiert Thomas Wycichowski Freitag, 2. August 2019 14:31
-
Hier auch noch der Code. Sicherlich könnte man das besser machen. Für meinen ersten versuch in C++ reicht mir das
int SetIe(HANDLE hClient) { DWORD dwResult = 0; PWLAN_RAW_DATA_LIST rawDataList = new WLAN_RAW_DATA_LIST(); LPCWSTR formatData = L"http://schemas.xmlsoaps.org/ws/2004/10/discovery"; char ieData[] = { '\x00', '\x01', '\x02', '\x03' }; rawDataList->dwTotalSize = 16 + sizeof(ieData); rawDataList->dwNumberOfItems = 1; rawDataList->DataList[0].dwDataOffset = 8; rawDataList->DataList[0].dwDataSize = sizeof(ieData); char* buffer = new char[rawDataList->dwTotalSize]; memcpy(&buffer, &rawDataList, sizeof(&rawDataList)); for (size_t i = 0, j = 16; i < sizeof(ieData); i++, j++) { buffer[j] = ieData[i]; } rawDataList = (PWLAN_RAW_DATA_LIST)buffer; return WlanSetPsdIEDataList(hClient, formatData, rawDataList, NULL); }
Gruß Thomas
13 Millionen Schweine landen jährlich im Müll
Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings -
Hallo Thomas,
dumme Fragen gibt es nicht. Man wird doch wohl untereinander laut denken dürfen ;-)
Im C++ Code bringst du einiges durcheinander. Ein memcpy() mit den Adressen von Zeigervariablen (also Zeiger auf Zeiger) ist wie eine normale Zuweisung einer Zeigervariablen mit =, die hier mit memcpy() sicher nicht gewollt ist. Dass das Beispiel nicht abstürzt, ist wohl eher Zufall ;-)
Im C++ sollte man immer an das delete denken. Dabei kommt es darauf an, ob ein Array oder ein einzelner Typ beim new angegeben wurde. Je nachdem ist 'delete' oder 'delete []' zu verwenden.
Die Struktur WLAN_RAW_DATA_LIST enthält keine Zeiger. Deshalb sollte man auch nicht beim Versuch, die Struktur im C# nachzubilden, einen Zeiger einbauen. Die Struktur enthält Daten, die im Speicher zusammenhängend sind. Da die Struktur eine dynamische Länge haben kann, muß man vorher die Größe des zu benötigten Speichers berechnen.
Sollte eine Struktur nicht nur aus DWORDs bestehen, sondern auch BYTEs und größere Typen gemischt beinhalten, muß man das Alignment beachten. Dadurch kann theoretisch sizeof(MY_STRUCT) größer sein, als die Summe ihrer Member. Das Alignment sollte man jedoch nicht ändern, besonders, wenn Strukturen Modul-übergreifend verwendet werden. (Siehe Projekt-Einstellungen/C++/Codegenerierung/Strukturmemberausrichtung) Bei WLAN_RAW_DATA_LIST spielt das Alignment keine Rolle, da hier nur DWORDs verwendet werden und durch das Alignment keine Lücken in der Struktur entstehen können.
Das Beispiel in der MSDN zu WLAN_RAW_DATA_LIST enthält in dwTotalSize 84. Das ist verwirrend, da meiner Meinung nach die resultierende Größe 68 ergibt.
Bei der Beschreibung der PSD-Struktur wird gesagt, dass die Length = (Länge der Daten + 8) sein soll. Die PSD-Header-Angaben nehmen jedoch 10 Bytes ein. => ebenfalls komisch.
Ich habe mal versucht, das Ganze nachzustellen. Auch mit mehreren PSD-Strukturen, also mit mehreren Blobs, funktioniert es, ERROR_SUCCESS.
In C# müßte man wohl alle Felder nach und nach in eine List<byte> einfügen. Dabei könnte man für die DWORDs folgendes verwenden:
uint totalSize = x; byteList.AddRange(BitConverter.GetBytes(totalSize));
Den Zeiger auf ein Array von byteList.ToArray() würde man dann an WlanSetPsdIEDataList() übergeben.
Ich hoffe, ich kann dir mit dem C++ etwas hilfreich sein und du bekommst wieder Lust am Projekt.
// WifiDirect.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include <windows.h> #include <wlanapi.h> struct BLOB_HEADER { DWORD dwOffset, dwSize; }; struct PSD { BYTE Id; BYTE Length; BYTE OUI[3]; BYTE OUIType; BYTE FormatIdentifierHash[4]; BYTE Data[230]; // Maximale Länge; Data kann kürzer sein. }; int _tmain(int argc, _TCHAR* argv[]); DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int size, BYTE * data); DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize1, BYTE * data1, int dataSize2, BYTE * data2, int dataSize3, BYTE * data3, int dataSize4, BYTE * data4, int dataSize5, BYTE * data5); void PrintResult(DWORD error); int _tmain(int argc, _TCHAR* argv[]) { DWORD ret, usedVersion; HANDLE hWlan; ret = WlanOpenHandle(2, NULL, &usedVersion, &hWlan); if (ret != ERROR_SUCCESS) { PrintResult(ret); return -1; } // Siehe https://docs.microsoft.com/de-de/windows/win32/api/wlanapi/nf-wlanapi-wlansetpsdiedatalist int size = sizeof(PSD); wchar_t * format = L"http://schemas.xmlsoaps.org/ws/2004/10/discovery"; PSD * pPsd = new PSD; memset(pPsd, 0, sizeof(PSD)); pPsd->Id = 221; pPsd->Length = 10; // 8; Die Länge soll PSD.Data + 8 sein. Die Felder in PSD vor PSD.Data sind jedoch 10 Bytes. ??? pPsd->OUI[0] = (BYTE)0x00; pPsd->OUI[1] = (BYTE)0x50; pPsd->OUI[2] = (BYTE)0xF2; pPsd->OUIType = 6; pPsd->FormatIdentifierHash[0] = 0xF8; pPsd->FormatIdentifierHash[1] = 0xCB; pPsd->FormatIdentifierHash[2] = 0x35; pPsd->FormatIdentifierHash[3] = 0x15; //BYTE data[] = { (BYTE)0x00, (BYTE)0x01, (BYTE)0x02, (BYTE)0x03 }; //size = sizeof(data); //ret = SetBlobs(hWlan, format, size, data); ret = SetBlobs(hWlan, format, size, (BYTE *)pPsd); if (ret == ERROR_SUCCESS) { // Test mit mehreren Blobs (bis zu 5; DOT11_PSD_IE_MAX_ENTRY_NUMBER) PSD psd2, psd3, psd4; memcpy(&psd2, pPsd, size); memcpy(&psd3, pPsd, size); memcpy(&psd4, pPsd, size); // ERROR_SUCCESS // ret = SetBlobs(hWlan, format, size, data, size, data, 0, NULL, 0, NULL, 0, NULL); // ret = SetBlobs(hWlan, format, size, (BYTE *)&psd2, 0, NULL, 0, NULL, 0, NULL, 0, NULL); ret = SetBlobs(hWlan, format, size, (BYTE *)pPsd, size, (BYTE *)&psd2, size, (BYTE *)&psd3, size, (BYTE *)&psd4, 0, NULL); } delete pPsd; WlanCloseHandle(hWlan, NULL); PrintResult(ret); return 0; } // Für genau einen Blob. DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize, BYTE * data) { // Ohne Blobs liefert WlanSetPsdIEDataList() auch ERROR_SUCCESS. /* WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[8]; pList->dwTotalSize = 8; pList->dwNumberOfItems = 0; DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); PrintResult(ret); delete[](BYTE *)pList; return ret; */ if (!hWlan || dataSize <= 0 || dataSize > DOT11_PSD_IE_MAX_DATA_SIZE || !data) return ERROR_INVALID_PARAMETER; int size = sizeof(WLAN_RAW_DATA_LIST) + dataSize; WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[size]; pList->dwTotalSize = size; // Die Angabe im Beispiel der MSDN ist widersprüchlich, statt 84 sollte dort 68 (nach meiner Meinung) stehen. pList->dwNumberOfItems = 1; pList->DataList[0].dwDataSize = dataSize; pList->DataList[0].dwDataOffset = 8; memcpy((BYTE *)pList + sizeof(WLAN_RAW_DATA_LIST), data, dataSize); DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); delete [](BYTE *)pList; return ret; } // Für 0 bis 5 Blobs. DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize1, BYTE * data1, int dataSize2, BYTE * data2, int dataSize3, BYTE * data3, int dataSize4, BYTE * data4, int dataSize5, BYTE * data5) { if (!hWlan) return ERROR_INVALID_PARAMETER; DWORD size = sizeof(BLOB_HEADER), dataOffset = 0, count = 0; if (dataSize1 < 0 || dataSize1 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize1 > 0 && !data1) return ERROR_INVALID_PARAMETER; else if (dataSize1 > 0) { size += sizeof(BLOB_HEADER) + dataSize1; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize2 < 0 || dataSize2 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize2 > 0 && !data2) return ERROR_INVALID_PARAMETER; else if (dataSize2 > 0) { size += sizeof(BLOB_HEADER) + dataSize2; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize3 < 0 || dataSize3 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize3 > 0 && !data3) return ERROR_INVALID_PARAMETER; else if (dataSize3 > 0) { size += sizeof(BLOB_HEADER) + dataSize3; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize4 < 0 || dataSize4 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize4 > 0 && !data4) return ERROR_INVALID_PARAMETER; else if (dataSize4 > 0) { size += sizeof(BLOB_HEADER) + dataSize4; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize5 < 0 || dataSize5 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize5 > 0 && !data5) return ERROR_INVALID_PARAMETER; else if (dataSize5 > 0) { size += sizeof(BLOB_HEADER) + dataSize5; dataOffset += sizeof(BLOB_HEADER); count++; } } } } } WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[size]; pList->dwTotalSize = size; pList->dwNumberOfItems = count; BLOB_HEADER * pBlobHeader = (BLOB_HEADER *)&pList->DataList; BYTE * pData = (BYTE *)&pList->DataList + dataOffset; if (count >= 1) { pBlobHeader->dwSize = dataSize1; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data1, dataSize1); if (count >= 2) { pBlobHeader++; pData += dataSize1; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize1; pBlobHeader->dwSize = dataSize2; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data2, dataSize2); if (count >= 3) { pBlobHeader++; pData += dataSize2; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize2; pBlobHeader->dwSize = dataSize3; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data3, dataSize3); if (count >= 4) { pBlobHeader++; pData += dataSize3; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize3; pBlobHeader->dwSize = dataSize4; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data4, dataSize4); if (count >= 5) { pBlobHeader++; pData += dataSize4; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize4; pBlobHeader->dwSize = dataSize5; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data5, dataSize5); } } } } } DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); // Da der Speicher für 'pList' als Array (von BYTEs) angefordert wurde, muß er auch als Array freigegeben werden. delete[](BYTE *)pList; return ret; } void PrintResult(DWORD error) { switch (error) { case ERROR_SUCCESS: puts("ERROR_SUCCESS"); break; case ERROR_INVALID_PARAMETER: puts("ERROR_INVALID_PARAMETER"); break; case ERROR_NOT_ENOUGH_MEMORY: puts("ERROR_NOT_ENOUGH_MEMORY"); break; case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: puts("ERROR_REMOTE_SESSION_LIMIT_EXCEEDED"); break; default: printf("0x%08X\r\n", error); break; } getchar(); }
Gruß,
Heiko
- Als Antwort markiert Thomas Wycichowski Samstag, 17. August 2019 17:15
- Bearbeitet Heiko65456465 Samstag, 17. August 2019 18:17 Korrektur im Code
-
Hallo Thomas,
in deinem Beispiel schreibst du Speicher kaputt, ohne dass es auffällt. Besser wäre es so:
DWORD SetIe(HANDLE hClient) { DWORD dwResult = 0; PWLAN_RAW_DATA_LIST rawDataList = new WLAN_RAW_DATA_LIST(); LPCWSTR formatData = L"http://schemas.xmlsoaps.org/ws/2004/10/discovery"; char ieData[] = { '\x00', '\x01', '\x02', '\x03' }; rawDataList->dwTotalSize = 16 + sizeof(ieData); rawDataList->dwNumberOfItems = 1; rawDataList->DataList[0].dwDataOffset = 8; rawDataList->DataList[0].dwDataSize = sizeof(ieData); char* buffer = new char[rawDataList->dwTotalSize]; // sizeof(&rawDataList) oder sizeof(rawDataList) würden nur 4 (bzw. 8 auf 64-Bit-OS) ergeben, da dies Zeiger sind. // memcpy(&buffer, &rawDataList, sizeof(&rawDataList)); memcpy(buffer, rawDataList, sizeof(WLAN_RAW_DATA_LIST)); for (size_t i = 0, j = 16; i < sizeof(ieData); i++, j++) { buffer[j] = ieData[i]; } // 'rawDataList' und 'buffer' sollten keine weitere Zuweisung erhalten, da ihr // Speicher wieder freigegeben werden muß. // rawDataList = (PWLAN_RAW_DATA_LIST)buffer; DWORD ret = WlanSetPsdIEDataList(hClient, formatData, (PWLAN_RAW_DATA_LIST)buffer, NULL); delete []buffer; delete rawDataList; // return WlanSetPsdIEDataList(hClient, formatData, rawDataList, NULL); return ret; }
Es ist jedoch nicht nötig, zwei mal Speicher anzufordern und zu kopieren, siehe dazu meine andere Antwort.
Gruß,
Heiko
- Bearbeitet Heiko65456465 Samstag, 17. August 2019 13:50
- Als Antwort markiert Thomas Wycichowski Samstag, 17. August 2019 17:15
-
Hallo Heiko,
danke für deine ausführliche Antwort und die Korrektur meiner Funktion, ich werde mir das genauer ansehen.
Soweit hat mein Code oben funktioniert. Ich konnte das Ergebnis auch mit Wireshark sehen. Leider ist mir erst dann aufgefallen das der OUI Typ 06 verwendet wird (wie in der Doku auch beschrieben wird). Ich brauchen aber den OUI Typ 04. Mit dieser Funktion lässt sich das nicht erreichen. Ich habe auch keine andere Funktion gefunden mit der man das erreichen könnte.
Jetzt habe ich mir den ESP32 von Espressif gekauft und mein erstes Ziel erreicht. Nun arbeite mich mit dem open Book von Rheinwerk C von A-Z in C ein. In ein paar Tagen verstehe ich das ganze sicherlich besser.
Gruß Thomas
13 Millionen Schweine landen jährlich im Müll
Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings -
Hallo Thomas,
da hier im Forum Antworten vom Wochenende verlorengingen, poste ich nochmal den Code. Den Text habe ich nicht mehr, den hattest du ja schon zur Kenntnis genommen.
DWORD SetIe(HANDLE hClient) { DWORD dwResult = 0; PWLAN_RAW_DATA_LIST rawDataList = new WLAN_RAW_DATA_LIST(); LPCWSTR formatData = L"http://schemas.xmlsoaps.org/ws/2004/10/discovery"; char ieData[] = { '\x00', '\x01', '\x02', '\x03' }; rawDataList->dwTotalSize = 16 + sizeof(ieData); rawDataList->dwNumberOfItems = 1; rawDataList->DataList[0].dwDataOffset = 8; rawDataList->DataList[0].dwDataSize = sizeof(ieData); char* buffer = new char[rawDataList->dwTotalSize]; // sizeof(&rawDataList) oder sizeof(rawDataList) würden nur 4 (bzw. 8 auf 64-Bit-OS) ergeben, da dies Zeiger sind. // memcpy(&buffer, &rawDataList, sizeof(&rawDataList)); memcpy(buffer, rawDataList, sizeof(WLAN_RAW_DATA_LIST)); for (size_t i = 0, j = 16; i < sizeof(ieData); i++, j++) { buffer[j] = ieData[i]; } // 'rawDataList' und 'buffer' sollten keine weitere Zuweisung erhalten, da ihr // speicher wieder freigegeben werden muß. // rawDataList = (PWLAN_RAW_DATA_LIST)buffer; DWORD ret = WlanSetPsdIEDataList(hClient, formatData, (PWLAN_RAW_DATA_LIST)buffer, NULL); delete []buffer; delete rawDataList; // return WlanSetPsdIEDataList(hClient, formatData, rawDataList, NULL); return ret; }
// WifiDirect.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung. // #include "stdafx.h" #include <windows.h> #include <wlanapi.h> struct BLOB_HEADER { DWORD dwOffset, dwSize; }; struct PSD { BYTE Id; BYTE Length; BYTE OUI[3]; BYTE OUIType; BYTE FormatIdentifierHash[4]; BYTE Data[230]; // Maximale Länge; Data kann kürzer sein. }; int _tmain(int argc, _TCHAR* argv[]); DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int size, BYTE * data); DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize1, BYTE * data1, int dataSize2, BYTE * data2, int dataSize3, BYTE * data3, int dataSize4, BYTE * data4, int dataSize5, BYTE * data5); void PrintResult(DWORD error); int _tmain(int argc, _TCHAR* argv[]) { DWORD ret, usedVersion; HANDLE hWlan; ret = WlanOpenHandle(2, NULL, &usedVersion, &hWlan); if (ret != ERROR_SUCCESS) { PrintResult(ret); return -1; } // Siehe https://docs.microsoft.com/de-de/windows/win32/api/wlanapi/nf-wlanapi-wlansetpsdiedatalist int size = sizeof(PSD); wchar_t * format = L"http://schemas.xmlsoaps.org/ws/2004/10/discovery"; PSD * pPsd = new PSD; memset(pPsd, 0, sizeof(PSD)); pPsd->Id = 221; pPsd->Length = 10; // 8; Die Länge soll PSD.Data + 8 sein. Die Felder in PSD vor PSD.Data sind jedoch 10 Bytes. ??? pPsd->OUI[0] = (BYTE)0x00; pPsd->OUI[1] = (BYTE)0x50; pPsd->OUI[2] = (BYTE)0xF2; pPsd->OUIType = 6; pPsd->FormatIdentifierHash[0] = 0xF8; pPsd->FormatIdentifierHash[1] = 0xCB; pPsd->FormatIdentifierHash[2] = 0x35; pPsd->FormatIdentifierHash[3] = 0x15; //BYTE data[] = { (BYTE)0x00, (BYTE)0x01, (BYTE)0x02, (BYTE)0x03 }; //size = sizeof(data); //ret = SetBlobs(hWlan, format, size, data); ret = SetBlobs(hWlan, format, size, (BYTE *)pPsd); if (ret == ERROR_SUCCESS) { // Test mit mehreren Blobs (bis zu 5; DOT11_PSD_IE_MAX_ENTRY_NUMBER) PSD psd2, psd3, psd4; memcpy(&psd2, pPsd, size); memcpy(&psd3, pPsd, size); memcpy(&psd4, pPsd, size); // ERROR_SUCCESS // ret = SetBlobs(hWlan, format, size, data, size, data, 0, NULL, 0, NULL, 0, NULL); // ret = SetBlobs(hWlan, format, size, (BYTE *)&psd2, 0, NULL, 0, NULL, 0, NULL, 0, NULL); ret = SetBlobs(hWlan, format, size, (BYTE *)pPsd, size, (BYTE *)&psd2, size, (BYTE *)&psd3, size, (BYTE *)&psd4, 0, NULL); } delete pPsd; WlanCloseHandle(hWlan, NULL); PrintResult(ret); return 0; } // Für genau einen Blob. DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize, BYTE * data) { // Ohne Blobs liefert WlanSetPsdIEDataList() auch ERROR_SUCCESS. /* WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[8]; pList->dwTotalSize = 8; pList->dwNumberOfItems = 0; DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); PrintResult(ret); delete[](BYTE *)pList; return ret; */ if (!hWlan || dataSize <= 0 || dataSize > DOT11_PSD_IE_MAX_DATA_SIZE || !data) return ERROR_INVALID_PARAMETER; int size = sizeof(WLAN_RAW_DATA_LIST) + dataSize; WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[size]; pList->dwTotalSize = size; // Die Angabe im Beispiel der MSDN ist widersprüchlich, statt 84 sollte dort 68 (nach meiner Meinung) stehen. pList->dwNumberOfItems = 1; pList->DataList[0].dwDataSize = dataSize; pList->DataList[0].dwDataOffset = 8; memcpy((BYTE *)pList + sizeof(WLAN_RAW_DATA_LIST), data, dataSize); DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); delete [](BYTE *)pList; return ret; } // Für 0 bis 5 Blobs. DWORD SetBlobs(HANDLE hWlan, wchar_t * format, int dataSize1, BYTE * data1, int dataSize2, BYTE * data2, int dataSize3, BYTE * data3, int dataSize4, BYTE * data4, int dataSize5, BYTE * data5) { if (!hWlan) return ERROR_INVALID_PARAMETER; DWORD size = sizeof(BLOB_HEADER), dataOffset = 0, count = 0; if (dataSize1 < 0 || dataSize1 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize1 > 0 && !data1) return ERROR_INVALID_PARAMETER; else if (dataSize1 > 0) { size += sizeof(BLOB_HEADER) + dataSize1; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize2 < 0 || dataSize2 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize2 > 0 && !data2) return ERROR_INVALID_PARAMETER; else if (dataSize2 > 0) { size += sizeof(BLOB_HEADER) + dataSize2; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize3 < 0 || dataSize3 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize3 > 0 && !data3) return ERROR_INVALID_PARAMETER; else if (dataSize3 > 0) { size += sizeof(BLOB_HEADER) + dataSize3; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize4 < 0 || dataSize4 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize4 > 0 && !data4) return ERROR_INVALID_PARAMETER; else if (dataSize4 > 0) { size += sizeof(BLOB_HEADER) + dataSize4; dataOffset += sizeof(BLOB_HEADER); count++; if (dataSize5 < 0 || dataSize5 > DOT11_PSD_IE_MAX_DATA_SIZE || dataSize5 > 0 && !data5) return ERROR_INVALID_PARAMETER; else if (dataSize5 > 0) { size += sizeof(BLOB_HEADER) + dataSize5; dataOffset += sizeof(BLOB_HEADER); count++; } } } } } WLAN_RAW_DATA_LIST * pList = (WLAN_RAW_DATA_LIST *)new BYTE[size]; pList->dwTotalSize = size; pList->dwNumberOfItems = count; BLOB_HEADER * pBlobHeader = (BLOB_HEADER *)&pList->DataList; BYTE * pData = (BYTE *)&pList->DataList + dataOffset; if (count >= 1) { pBlobHeader->dwSize = dataSize1; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data1, dataSize1); if (count >= 2) { pBlobHeader++; pData += dataSize1; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize1; pBlobHeader->dwSize = dataSize2; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data2, dataSize2); if (count >= 3) { pBlobHeader++; pData += dataSize2; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize2; pBlobHeader->dwSize = dataSize3; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data3, dataSize3); if (count >= 4) { pBlobHeader++; pData += dataSize3; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize3; pBlobHeader->dwSize = dataSize4; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data4, dataSize4); if (count >= 5) { pBlobHeader++; pData += dataSize4; dataOffset -= sizeof(BLOB_HEADER); dataOffset += dataSize4; pBlobHeader->dwSize = dataSize5; pBlobHeader->dwOffset = dataOffset; memcpy(pData, data5, dataSize5); } } } } } DWORD ret = WlanSetPsdIEDataList(hWlan, format, pList, NULL); // Da der Speicher für 'pList' als Array (von BYTEs) angefordert wurde, muß er auch als Array freigegeben werden. delete[](BYTE *)pList; return ret; } void PrintResult(DWORD error) { switch (error) { case ERROR_SUCCESS: puts("ERROR_SUCCESS"); break; case ERROR_INVALID_PARAMETER: puts("ERROR_INVALID_PARAMETER"); break; case ERROR_NOT_ENOUGH_MEMORY: puts("ERROR_NOT_ENOUGH_MEMORY"); break; case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED: puts("ERROR_REMOTE_SESSION_LIMIT_EXCEEDED"); break; default: printf("0x%08X\r\n", error); break; } getchar(); }
Gruß,
Heiko- Als Antwort markiert Thomas Wycichowski Dienstag, 20. August 2019 15:54
- Tag als Antwort aufgehoben Thomas Wycichowski Dienstag, 20. August 2019 17:18
- Als Antwort markiert Thomas Wycichowski Dienstag, 20. August 2019 20:37
-
Hallo Heiko,
ganz richtig ist dein Beispiel nicht. Man kann keine OUI setzen, sie die wird von MS festgelegt und sie ist immer 0x0050F206. Die Msg wir nur an das IE angehängt
Gruß Thomas
13 Millionen Schweine landen jährlich im Müll
Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings- Bearbeitet Thomas Wycichowski Dienstag, 20. August 2019 20:25
-
Hallo Thomas,
eigentlich ging es mir nur darum, zu zeigen, wie man die WLAN_RAW_DATA_LIST-Struktur im C++ dynamisch aufbauen und füllen kann. Da bei mir anfangs WlanSetPsdIEDataList() nicht ERROR_SUCCESS zurück gab, dachte ich, man müsste auch die PSD-Struktur benutzen und tippte einfach ab, was auf der MSDN-Seite steht. Letzten Endes war es dann aber egal, was man als Blob übergibt, oder ob die PSD-Struktur richtig gefüllt ist, es hätte auch mit 0123 funktioniert.
Gruß,
Heiko
-
Dein Beispiel ist auch sehr gut. Wollte das nur klar stellen.
Gruß Thomas
13 Millionen Schweine landen jährlich im Müll
Dev Apps von mir: UWP Segoe MDL2 Assets, UI Strings