int __cdecl mblen ( const char * s, size_t n ) { _ASSERTE (MB_CUR_MAX == 1 || MB_CUR_MAX == 2); if ( !s || !(*s) || (n == 0) ) /* indicate do not have state-dependent encodings, empty string length is 0 */ return 0; #if !defined(_NTSUBSET_) && !defined(_POSIX_) if ( isleadbyte((unsigned char)*s) ) { /* multi-byte char */ /* verify valid MB char */ #ifdef _WIN32 if ( MB_CUR_MAX <= 1 || (int)n < MB_CUR_MAX || MultiByteToWideChar(__lc_codepage, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, s, MB_CUR_MAX, NULL, 0) == 0 ) #else /* validate high byte of mbcs char */ if ((n<(size_t)MB_CUR_MAX) || (!*(s+1))) #endif /* _WIN32 */ /* bad MB char */ return -1; else return MB_CUR_MAX; } else { /* single byte char */ #ifdef _WIN32 /* verify valid SB char */ if ( MultiByteToWideChar(__lc_codepage, MB_PRECOMPOSED|MB_ERR_INVALID_CHARS, s, 1, NULL, 0) == 0 ) return -1; #endif /* _WIN32 */ return sizeof(char); } #else /* _NTSUBSET_ */ { char *s1 = (char *)s; RtlAnsiCharToUnicodeChar( &s1 ); return s1 - s; } #endif /* _NTSUBSET_ */ }
/* * @implemented */ int mbtowc (wchar_t *wchar, const char *mbchar, size_t count) { UCHAR mbarr[MB_CUR_MAX] = { 0 }; PUCHAR mbs = mbarr; WCHAR wc; if (mbchar == NULL) return 0; if (wchar == NULL) return 0; memcpy(mbarr, mbchar, min(count, sizeof mbarr)); wc = RtlAnsiCharToUnicodeChar(&mbs); if (wc == L' ' && mbarr[0] != ' ') return -1; *wchar = wc; return (int)(mbs - mbarr); }
/*********************************************************************** * GetTempFileNameW (KERNEL32.@) */ UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName) { CHAR * Let; HANDLE TempFile; UINT ID, Num = 0; CHAR IDString[5]; WCHAR * TempFileName; BASE_API_MESSAGE ApiMessage; PBASE_GET_TEMP_FILE GetTempFile = &ApiMessage.Data.GetTempFileRequest; DWORD FileAttributes, LastError; UNICODE_STRING PathNameString, PrefixString; static const WCHAR Ext[] = { L'.', 't', 'm', 'p', UNICODE_NULL }; RtlInitUnicodeString(&PathNameString, lpPathName); if (PathNameString.Length == 0 || PathNameString.Buffer[(PathNameString.Length / sizeof(WCHAR)) - 1] != L'\\') { PathNameString.Length += sizeof(WCHAR); } /* lpTempFileName must be able to contain: PathName, Prefix (3), number(4), .tmp(4) & \0(1) * See: http://msdn.microsoft.com/en-us/library/aa364991%28v=vs.85%29.aspx */ if (PathNameString.Length > (MAX_PATH - 3 - 4 - 4 - 1) * sizeof(WCHAR)) { SetLastError(ERROR_BUFFER_OVERFLOW); return 0; } /* If PathName and TempFileName aren't the same buffer, move PathName to TempFileName */ if (lpPathName != lpTempFileName) { memmove(lpTempFileName, PathNameString.Buffer, PathNameString.Length); } /* PathName MUST BE a path. Check it */ lpTempFileName[(PathNameString.Length / sizeof(WCHAR)) - 1] = UNICODE_NULL; FileAttributes = GetFileAttributesW(lpTempFileName); if (FileAttributes == INVALID_FILE_ATTRIBUTES) { /* Append a '\' if necessary */ lpTempFileName[(PathNameString.Length / sizeof(WCHAR)) - 1] = L'\\'; lpTempFileName[PathNameString.Length / sizeof(WCHAR)] = UNICODE_NULL; FileAttributes = GetFileAttributesW(lpTempFileName); if (FileAttributes == INVALID_FILE_ATTRIBUTES) { SetLastError(ERROR_DIRECTORY); return 0; } } if (!(FileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { SetLastError(ERROR_DIRECTORY); return 0; } /* Make sure not to mix path & prefix */ lpTempFileName[(PathNameString.Length / sizeof(WCHAR)) - 1] = L'\\'; RtlInitUnicodeString(&PrefixString, lpPrefixString); if (PrefixString.Length > 3 * sizeof(WCHAR)) { PrefixString.Length = 3 * sizeof(WCHAR); } /* Append prefix to path */ TempFileName = lpTempFileName + PathNameString.Length / sizeof(WCHAR); memmove(TempFileName, PrefixString.Buffer, PrefixString.Length); TempFileName += PrefixString.Length / sizeof(WCHAR); /* Then, generate filename */ do { /* If user didn't gave any ID, ask Csrss to give one */ if (!uUnique) { CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, NULL, CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepGetTempFile), sizeof(BASE_GET_TEMP_FILE)); if (GetTempFile->UniqueID == 0) { Num++; continue; } ID = GetTempFile->UniqueID; } else { ID = uUnique; } /* Convert that ID to wchar */ RtlIntegerToChar(ID, 0x10, sizeof(IDString), IDString); Let = IDString; do { *(TempFileName++) = RtlAnsiCharToUnicodeChar(&Let); } while (*Let != 0); /* Append extension & UNICODE_NULL */ memmove(TempFileName, Ext, sizeof(Ext)); /* If user provided its ID, just return */ if (uUnique) { return uUnique; } /* Then, try to create file */ if (!RtlIsDosDeviceName_U(lpTempFileName)) { TempFile = CreateFileW(lpTempFileName, GENERIC_READ, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); if (TempFile != INVALID_HANDLE_VALUE) { NtClose(TempFile); DPRINT("Temp file: %S\n", lpTempFileName); return ID; } LastError = GetLastError(); /* There is no need to recover from those errors, they would hit next step */ if (LastError == ERROR_INVALID_PARAMETER || LastError == ERROR_CANNOT_MAKE || LastError == ERROR_WRITE_PROTECT || LastError == ERROR_NETWORK_ACCESS_DENIED || LastError == ERROR_DISK_FULL || LastError == ERROR_INVALID_NAME || LastError == ERROR_BAD_PATHNAME || LastError == ERROR_NO_INHERITANCE || LastError == ERROR_DISK_CORRUPT || (LastError == ERROR_ACCESS_DENIED && NtCurrentTeb()->LastStatusValue != STATUS_FILE_IS_A_DIRECTORY)) { break; } } Num++; } while (Num & 0xFFFF); return 0; }