error helper - GetLastError() is provided, but this is for exceptions */
| 285 | |
| 286 | /* error helper - GetLastError() is provided, but this is for exceptions */ |
| 287 | PyObject *PyWin_SetAPIError(char *fnName, long err /*= 0*/) |
| 288 | { |
| 289 | DWORD errorCode = err == 0 ? GetLastError() : err; |
| 290 | DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | \ |
| 291 | FORMAT_MESSAGE_IGNORE_INSERTS; |
| 292 | // try and find the hmodule providing this error. |
| 293 | HMODULE hmodule = PyWin_GetErrorMessageModule(errorCode); |
| 294 | if (hmodule) |
| 295 | flags |= FORMAT_MESSAGE_FROM_HMODULE; |
| 296 | TCHAR *buf = NULL; |
| 297 | BOOL free_buf = TRUE; |
| 298 | if (errorCode) |
| 299 | ::FormatMessage(flags, hmodule, errorCode, 0, (LPTSTR)&buf, 0, NULL ); |
| 300 | if (!buf) { |
| 301 | buf = _T("No error message is available"); |
| 302 | free_buf = FALSE; |
| 303 | } |
| 304 | /* strip trailing cr/lf */ |
| 305 | size_t end = _tcslen(buf)-1; |
| 306 | if (end>1 && (buf[end-1]==_T('\n') || buf[end-1]==_T('\r'))) |
| 307 | buf[end-1] = _T('\0'); |
| 308 | else |
| 309 | if (end>0 && (buf[end]==_T('\n') || buf[end]==_T('\r'))) |
| 310 | buf[end]=_T('\0'); |
| 311 | |
| 312 | PyObject *v = Py_BuildValue("(iNN)", |
| 313 | errorCode, |
| 314 | PyWinCoreString_FromString(fnName), |
| 315 | PyWinObject_FromTCHAR(buf)); |
| 316 | if (free_buf && buf) |
| 317 | LocalFree(buf); |
| 318 | if (v != NULL) { |
| 319 | PyErr_SetObject(PyWinExc_ApiError, v); |
| 320 | Py_DECREF(v); |
| 321 | } |
| 322 | return NULL; |
| 323 | } |
| 324 | |
| 325 | // This function sets a basic COM error - it is a valid COM |
| 326 | // error, but may not contain rich error text about the error. |
no test coverage detected