/* * Win32 miscellaneous functions * * Copyright 1995 Thomas Sandford (tdgsandf@prds-grn.demon.co.uk) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Misc. new functions - they should be moved into appropriate files at a later date. */ #include "config.h" #include "wine/port.h" #include #include #ifdef HAVE_SYS_TIME_H # include #endif #ifdef HAVE_UNISTD_H # include #endif #include "windef.h" #include "winbase.h" #include "winnls.h" #include "winerror.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(win32); WINE_DECLARE_DEBUG_CHANNEL(debug); static BOOL QUERYPERF_Initialized = 0; #if defined(__i386__) && defined(__GNUC__) static BOOL QUERYPERF_RDTSC_Use = 0; static LONGLONG QUERYPERF_RDTSC_Frequency = 0; #endif static void QUERYPERF_Init(void) { #if defined(__i386__) && defined(__GNUC__) /* We are running on i386 and compiling on GCC. * Do a runtime check to see if we have the rdtsc instruction available */ FILE *fp; char line[256], *s, *value; double cpuMHz; TRACE("()\n"); if (IsProcessorFeaturePresent( PF_RDTSC_INSTRUCTION_AVAILABLE )) { /* rdtsc is available. However, in order to use it * we also need to be able to get the processor's * speed. Currently we do this by reading /proc/cpuinfo * which makes it Linux-specific. */ TRACE("rdtsc available\n"); fp = fopen( "/proc/cpuinfo", "r" ); if (fp) { while(fgets( line, sizeof(line), fp )) { /* NOTE: the ':' is the only character we can rely on */ if (!(value = strchr( line, ':' ))) continue; /* terminate the valuename */ *value++ = '\0'; /* skip any leading spaces */ while (*value == ' ') value++; if ((s = strchr( value, '\n' ))) *s = '\0'; if (!strncasecmp( line, "cpu MHz", strlen( "cpu MHz" ) )) { if (sscanf( value, "%lf", &cpuMHz ) == 1) { QUERYPERF_RDTSC_Frequency = (LONGLONG)(cpuMHz * 1000000.0); QUERYPERF_RDTSC_Use = TRUE; TRACE("using frequency: %lldHz\n", QUERYPERF_RDTSC_Frequency); break; } } } fclose(fp); } } #endif QUERYPERF_Initialized = TRUE; } /**************************************************************************** * QueryPerformanceCounter (KERNEL32.@) */ BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER counter) { struct timeval tv; if (!QUERYPERF_Initialized) QUERYPERF_Init(); #if defined(__i386__) && defined(__GNUC__) if (QUERYPERF_RDTSC_Use) { /* i586 optimized version */ __asm__ __volatile__ ( "rdtsc" : "=a" (counter->s.LowPart), "=d" (counter->s.HighPart) ); return TRUE; } /* fall back to generic routine (ie, for i386, i486) */ #endif /* generic routine */ gettimeofday( &tv, NULL ); counter->QuadPart = (LONGLONG)tv.tv_usec + (LONGLONG)tv.tv_sec * 1000000; return TRUE; } /**************************************************************************** * QueryPerformanceFrequency (KERNEL32.@) */ BOOL WINAPI QueryPerformanceFrequency(PLARGE_INTEGER frequency) { if (!QUERYPERF_Initialized) QUERYPERF_Init(); #if defined(__i386__) && defined(__GNUC__) if (QUERYPERF_RDTSC_Use) { frequency->QuadPart = QUERYPERF_RDTSC_Frequency; return TRUE; } #endif frequency->s.LowPart = 1000000; frequency->s.HighPart = 0; return TRUE; } /**************************************************************************** * FlushInstructionCache (KERNEL32.@) */ BOOL WINAPI FlushInstructionCache(HANDLE hProcess, LPCVOID lpBaseAddress, DWORD dwSize) { if (GetVersion() & 0x80000000) return TRUE; /* not NT, always TRUE */ FIXME_(debug)("(0x%08lx,%p,0x%08lx): stub\n",(DWORD)hProcess, lpBaseAddress, dwSize); return TRUE; } /*********************************************************************** * GetSystemPowerStatus (KERNEL32.@) */ BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS sps_ptr) { return FALSE; /* no power management support */ } /*********************************************************************** * SetSystemPowerState (KERNEL32.@) */ BOOL WINAPI SetSystemPowerState(BOOL suspend_or_hibernate, BOOL force_flag) { /* suspend_or_hibernate flag: w95 does not support this feature anyway */ for ( ;0; ) { if ( force_flag ) { } else { } } return TRUE; } /****************************************************************************** * CreateMailslotA [KERNEL32.@] */ HANDLE WINAPI CreateMailslotA( LPCSTR lpName, DWORD nMaxMessageSize, DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa) { FIXME("(%s,%ld,%ld,%p): stub\n", debugstr_a(lpName), nMaxMessageSize, lReadTimeout, sa); return (HANDLE)1; } /****************************************************************************** * CreateMailslotW [KERNEL32.@] Creates a mailslot with specified name * * PARAMS * lpName [I] Pointer to string for mailslot name * nMaxMessageSize [I] Maximum message size * lReadTimeout [I] Milliseconds before read time-out * sa [I] Pointer to security structure * * RETURNS * Success: Handle to mailslot * Failure: INVALID_HANDLE_VALUE */ HANDLE WINAPI CreateMailslotW( LPCWSTR lpName, DWORD nMaxMessageSize, DWORD lReadTimeout, LPSECURITY_ATTRIBUTES sa ) { FIXME("(%s,%ld,%ld,%p): stub\n", debugstr_w(lpName), nMaxMessageSize, lReadTimeout, sa); return (HANDLE)1; } /****************************************************************************** * GetMailslotInfo [KERNEL32.@] Retrieves info about specified mailslot * * PARAMS * hMailslot [I] Mailslot handle * lpMaxMessageSize [O] Address of maximum message size * lpNextSize [O] Address of size of next message * lpMessageCount [O] Address of number of messages * lpReadTimeout [O] Address of read time-out * * RETURNS * Success: TRUE * Failure: FALSE */ BOOL WINAPI GetMailslotInfo( HANDLE hMailslot, LPDWORD lpMaxMessageSize, LPDWORD lpNextSize, LPDWORD lpMessageCount, LPDWORD lpReadTimeout ) { FIXME("(%04x): stub\n",hMailslot); if (lpMaxMessageSize) *lpMaxMessageSize = (DWORD)NULL; if (lpNextSize) *lpNextSize = (DWORD)NULL; if (lpMessageCount) *lpMessageCount = (DWORD)NULL; if (lpReadTimeout) *lpReadTimeout = (DWORD)NULL; return TRUE; } /****************************************************************************** * GetCompressedFileSizeA [KERNEL32.@] * * NOTES * This should call the W function below */ DWORD WINAPI GetCompressedFileSizeA( LPCSTR lpFileName, LPDWORD lpFileSizeHigh) { FIXME("(...): stub\n"); return 0xffffffff; } /****************************************************************************** * GetCompressedFileSizeW [KERNEL32.@] * * RETURNS * Success: Low-order doubleword of number of bytes * Failure: 0xffffffff */ DWORD WINAPI GetCompressedFileSizeW( LPCWSTR lpFileName, /* [in] Pointer to name of file */ LPDWORD lpFileSizeHigh) /* [out] Receives high-order doubleword of size */ { FIXME("(%s,%p): stub\n",debugstr_w(lpFileName),lpFileSizeHigh); return 0xffffffff; } /****************************************************************************** * SetComputerNameA [KERNEL32.@] */ BOOL WINAPI SetComputerNameA( LPCSTR lpComputerName ) { BOOL ret; DWORD len = MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, NULL, 0 ); LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ); MultiByteToWideChar( CP_ACP, 0, lpComputerName, -1, nameW, len ); ret = SetComputerNameW( nameW ); HeapFree( GetProcessHeap(), 0, nameW ); return ret; } /****************************************************************************** * SetComputerNameW [KERNEL32.@] * * PARAMS * lpComputerName [I] Address of new computer name * * RETURNS STD */ BOOL WINAPI SetComputerNameW( LPCWSTR lpComputerName ) { FIXME("(%s): stub\n", debugstr_w(lpComputerName)); return TRUE; } /****************************************************************************** * CreateIoCompletionPort (KERNEL32.@) */ HANDLE WINAPI CreateIoCompletionPort(HANDLE hFileHandle, HANDLE hExistingCompletionPort, DWORD dwCompletionKey, DWORD dwNumberOfConcurrentThreads) { FIXME("(%04x, %04x, %08lx, %08lx): stub.\n", hFileHandle, hExistingCompletionPort, dwCompletionKey, dwNumberOfConcurrentThreads); return (HANDLE)NULL; } /****************************************************************************** * GetQueuedCompletionStatus (KERNEL32.@) */ BOOL WINAPI GetQueuedCompletionStatus( HANDLE CompletionPort, LPDWORD lpNumberOfBytesTransferred, LPDWORD lpCompletionKey, LPOVERLAPPED *lpOverlapped, DWORD dwMilliseconds ) { FIXME("(%x,%p,%p,%p,%ld), stub!\n",CompletionPort,lpNumberOfBytesTransferred,lpCompletionKey,lpOverlapped,dwMilliseconds); SetLastError(ERROR_CALL_NOT_IMPLEMENTED); return FALSE; }