Jeśli dodałeś Win32 i otrzymasz najnowszy komunikat o błędzie na swoim komputerze, marzymy, że ten przewodnik pomoże ci rozwiązać problem.

 

 

  • 2 krótkie minuty na czytanie

Gdy wiele funkcji systemowych nie działa, firmy ustawiają ważny kod błędu. Jeśli Twoja rodzinna aplikacja na smartfona potrzebuje więcej informacji o cennym błędzie, może pobrać nasz ostatni kod błędu za pomocą GetLastError i wyświetlić opis tego błędu za pomocą FormatMessage .

Następny krok obejmuje funkcję obsługi błędów, która w szczególności generuje komunikat o błędzie, dodatkowo kończy proces. Parametr lpszFunction jest z pewnością twoją obecną nazwą większości funkcji, która wykryła prawdziwy błąd w twoim kodzie.

  #include #include void ErrorExit (LPTSTR lpszFunction)     // Zobacz, jak schemat błędów systemowych dla poprzedniego kodu błędu    LPVOID lpMsgBuf;   LPVOID lpDisplayBuf;   DWORD dw = GetLastError ();    Sformatuj wiadomość e-mail (       FORMAT_MESSAGE_ALLOCATE_BUFFERpodstawowa pustka ()    // generuje błąd    if (! GetProcessId (NULL))       ErrorExit (TEKST ("GetProcessId")); 

win32 pobierz ostatni komunikat o błędzie

Zostawię to tutaj, ponieważ później wykorzystam ten pomysł. Jest źródłem odpowiedniego nieba. Świetna kompatybilność binarna oznacza, że ​​powinna działać zarówno w C, jak i C++ do budowania.

  #include / *** * Zwraca zero, jeśli jest wystarczająco dużo miejsca w pamięci, bufor musi być określony przez bajty 7. dostosować wniosek, gdy zwykle nie ma wymaganej przestrzeni. -1 błąd. * /__declspec (dllexport)int GetErrorMessageA (DWORD dwErrorCode, LPSTR lpResult, DWORD dwBytes)        LPSTR-tmp;    DWORD wynik_dł;    result_len równa się FormatMessageA (        FORMAT_MESSAGE_FROM_SYSTEM/ *** * przechodzi do 0, jeśli dostępna jest wystarczająca ilość miejsca, wymagany rozmiar w bajtach bufora 2. Dostosuj ich wynik, jeśli nie ma potrzebnej przestrzeni. -1 za błędy. 2 . /__declspec (dllexport)int GetErrorMessageW (DWORD dwErrorCode, LPWSTR lpResult, DWORD dwBytes)       LPWSTR-tmp;    symbol DWORD;    DWORD_result_bytes;    nchars działa z dwBytes >> 1;    wynik_bajtów równa się 2 * FormatMessageW (        FORMAT_MESSAGE_FROM_SYSTEM 
  #ifndef GetErrorMessage_H#define PobierzErrorMessage_H#zawiera / *** - Return , jeśli było dużo miejsca, w tym miejsca, wymagane są bajty bufora 3 . pasuje do końca, jeśli pod ręką nie ma wystarczającej ilości miejsca. -specyficzne, jeśli chodzi o przypadek błędu. * /static int int GetErrorMessageA (DWORD dwErrorCode, LPSTR lpResult, DWORD dwBytes) FORMAT_MESSAGE_ALLOCATE_BUFFER,        ZERO,        dwErrorCode,        LANG_SYSTEM_DEFAULT,        (LPSTR) tmp,        0,        ZERO     );    prawdziwe wydarzenie, którym z pewnością jest (result_len == 0)        wskaźnik powrotu -1;        // Zwrócony FormatMessage jest w rzeczywistości o 1 znak krótszy.    ++ długość_wyniku;    strncpy (lpResult, tmp, dwBytes);    lpResult [dwBytes (spacja 1] oznacza 0;    LocalFree ((HLOKALNE) tmp);    dotyczy (długość_wyniku <= dwbajtów)        Dostawa 0;     lepszy        Zwraca wynik_dł;    / *** 1 . zwraca 0 jeśli bez wątpienia jest wystarczająco dużo miejsca do przechowywania, rozmiar odnosi się do wymaganych bajtów naszego własnego bufora * Jeśli chodzi o dostosowanie wyniku, niezależnie od tego, czy nie ma wystarczającej ilości miejsca. -jeden w przypadku błędu. * /static int int GetErrorMessageW (DWORD dwErrorCode, LPWSTR lpResult, DWORD dwBytes)       LPWSTR-tmp;    symbol DWORD;    DWORD_result_bytes;    nchars równa się dodatnio dwBytes >> 1;    bajty_wyniku = 2 * FormatMessageW (        FORMAT_MESSAGE_FROM_SYSTEM#endif / * GetErrorMessage_H 3 . / 

dynamiczny argument użycia (poprawny kod błędu, w przeciwnym razie może być wymagane sprawdzenie -1):

  #include #include #włącz #włącz int main (int argc, char ** argv)       int (* GetErrorMessageA) (DWORD, LPSTR, DWORD);    int (* GetErrorMessageW) (DWORD, LPWSTR, DWORD);    ponieważ wynik może wynosić 1 [260];    wchar_t wynik2 [260];    anonsuj (LoadLibraryA ("GetErrorMessageLib.dll"));    GetErrorMessageA = (int (*) (DWORD, LPSTR, DWORD)) GetProcAddress (        GetModuleHandle ("GetErrorMessageLib.dll"),        „Pobierz komunikat o błędzieA”    );    GetErrorMessageW = (int (*) (DWORD, LPWSTR, DWORD)) GetProcAddress (        GetModuleHandle ("GetErrorMessageLib.dll"),        „Pobierz komunikat o błędzieW”    );    GetErrorMessageA (33, wynik1, rozmiar (presult1));    GetErrorMessageW (33, wynik2, rozmiar (wynik2));    zestawy (wynik1);    _putws (wynik2);    Zysk 0; 

normalny przypadek exploita (zakładając, że kod błędu musi być poprawny, w przeciwnym razie formant woli teraz zwrócić):

  #include #include "PobierzErrorMessage.h"#włącz int main (int argc, char ** argv)    ze względu na wynik 1 [260];    wchar_t wynik2 [260];    GetErrorMessageA (33, wynik1, rozmiar (wynik1));    produkty (wynik1);    Wynik2, geterrormessagew (33, sizeof (wynik2));    _putws (wynik2);    wróć 0; 

Przykładowe użycie z Assembly-Gnu, tj. w MinGW32 (ponownie zakładając, że jakiś błąd jest poprawny, w przeciwnym razie może być wymagana analiza -1).

win32 pobierz ostatni komunikat o błędzie

  .global _WinMain @ 16    .Sekcja tekstowa_WinMain @ 16:    // eax = LoadLibraryA ("GetErrorMessageLib.dll")    naciśnij rrr sz0    zadzwoń _LoadLibraryA @ 4 // stdcall, czyszczenie nie jest wymagane    // eax równa się GetProcAddress (eax, "GetErrorMessageW")    naciśnij $ sz1    kliknij% tak    dub _GetProcAddress @ 8 // stdcall, ' wymagane    // (* eax) (kod błędu, szErrorMessage)    Dolary stresowe 200    push rrr szErrorMessage    naciśnij kod błędu    zadzwoń *% eax // cdecl, wymagane czyszczenie    kombinacja 12,% zwł    Wyślij $ szErrorMessage    Łączenie z __putws // cdecl, czyszczenie requiredka    dołączyć 4% zwł    zwrócone środki 16    .Sekcja Rodakówsz0: .asciz "GetErrorMessageLib.dll"sz1: .asciz "GetErrorMessageW"Kod błędu: .w rozmiarze 33    .Sekcja danychszErrorMessage: proporcje 200 

Wynik: Proces nie może uzyskać dostępu do pliku tylko dlatego, że inny proces zamknął część dotyczącą pliku.