| /* |
| * 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 <stdio.h> |
| #include <string.h> |
| #ifdef HAVE_SYS_TIME_H |
| # include <sys/time.h> |
| #endif |
| #ifdef HAVE_UNISTD_H |
| # include <unistd.h> |
| #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 * 1000000LL; |
| 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; |
| } |