Rebase our patches on wine-1.7.19

I've confirmed this
 - can compile on gTrusty
 - can work with VS2013-update2 (I've compiled chrome on this)
 - can work with VS2014-CTP

Also, now we don't need TLS-hack any more. So, I've remove such changes
from this CL.

The followings are patches this CL contains.

- workaround fix SetThreadPreferredUILanguages
- workaround fix LoadLibrary for datafile?
- Implement SRWLock
- FIXME->TRACE for SRWLock
- add WINEELFLOADER hack to wine-preloader
- Use timeout for futex_wait in SRWLock
- Add WINENOWINEBOOT environment variable to disable wineboot
- A simple hello world becomes faster (0.121 => 0.024).
- Add codereview.settings
- Workaround for VS2013
-- Workaround for cl.exe deadlock for VS2013.
-- cl.exe for VS2013 sometimes cannot find headers.
- Make wineserver exit immediately

Change-Id: I8c2f39c9f73947bfd644141c14a78aea0b075fd0
diff --git a/codereview.settings b/codereview.settings
new file mode 100644
index 0000000..aa631d7
--- /dev/null
+++ b/codereview.settings
@@ -0,0 +1,6 @@
+# This file is used by git-cl to get repository specific information.
+GERRIT_HOST: goma.googlesource.com
+GERRIT_PORT: 443
+CODE_REVIEW_SERVER: goma-review.googlesource.com
+# gerrit only accepts regiestered users for cc.
+# CC_LIST: goma+review@google.com
diff --git a/dlls/kernel32/module.c b/dlls/kernel32/module.c
index d1555f1..f3adb0a 100644
--- a/dlls/kernel32/module.c
+++ b/dlls/kernel32/module.c
@@ -904,8 +904,13 @@
         LOAD_LIBRARY_SEARCH_SYSTEM32 |
         LOAD_LIBRARY_SEARCH_DEFAULT_DIRS;
 
-    if( flags & unsupported_flags)
-        FIXME("unsupported flag(s) used (flags: 0x%08x)\n", flags);
+    if( flags & unsupported_flags) {
+        FIXME("%s unsupported flag(s) used (flags: 0x%08x)\n", debugstr_wn( libname->Buffer, libname->Length / sizeof(WCHAR) ), flags);
+	if (flags & (LOAD_LIBRARY_AS_IMAGE_RESOURCE|LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE)) {
+		flags |= LOAD_LIBRARY_AS_DATAFILE;
+		FIXME("fix flag: 0x%08x)\n", flags);
+	}
+    }
 
     load_path = MODULE_get_dll_load_path( flags & LOAD_WITH_ALTERED_SEARCH_PATH ? libname->Buffer : NULL );
 
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 0b70a55..796622d 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -997,6 +997,8 @@
  */
 static void start_wineboot( HANDLE handles[2] )
 {
+    if (getenv("WINENOWINEBOOT"))
+        return;
     static const WCHAR wineboot_eventW[] = {'_','_','w','i','n','e','b','o','o','t','_','e','v','e','n','t',0};
 
     handles[1] = 0;
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c
index 5d87cdd..ed3a00a 100644
--- a/dlls/kernel32/thread.c
+++ b/dlls/kernel32/thread.c
@@ -25,6 +25,9 @@
 #include <fcntl.h>
 #include <stdarg.h>
 #include <sys/types.h>
+#ifdef HAVE_SYS_SYSCALL_H
+#include <sys/syscall.h>
+#endif
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif
@@ -827,8 +830,215 @@
  */
 BOOL WINAPI GetThreadPreferredUILanguages( DWORD flags, PULONG count, PCZZWSTR buffer, PULONG buffersize )
 {
-    FIXME( "%u, %p, %p %p\n", flags, count, buffer, buffersize );
+    FIXME( "%u, %p(%d), %p %p(%d)\n", flags, count, *count, buffer, buffersize, *buffersize );
     *count = 0;
-    *buffersize = 0;
+    if (buffer == NULL) {
+	    *buffersize = 2;
+    } else {
+	    memset(buffer, 0, *buffersize*sizeof(WCHAR));
+    }
     return TRUE;
 }
+
+// TODO(ukai): move ntdlls/critsection.c?
+
+// copy from ntdlls/critsection.c
+#ifdef __linux__
+
+static int wait_op = 128; /*FUTEX_WAIT|FUTEX_PRIVATE_FLAG*/
+static int wake_op = 129; /*FUTEX_WAKE|FUTEX_PRIVATE_FLAG*/
+
+static inline int futex_wait( int *addr, int val, struct timespec *timeout )
+{
+    return syscall( SYS_futex, addr, wait_op, val, timeout, 0, 0 );
+}
+
+static inline int futex_wake( int *addr, int val )
+{
+    return syscall( SYS_futex, addr, wake_op, val, NULL, 0, 0 );
+}
+
+// srwlock->Ptr
+#define SRW_LOCKED 0x80000000
+#define SRW_WRITE_ACTIVE 0x00800000
+#define SRW_READERS_ACTIVE_MASK 0x0000FFFF
+
+void lock_srwlock(PSRWLOCK srwlock) {
+  TRACE("lock (%p %p)\n", srwlock, srwlock->Ptr);
+  DWORD oldval = 0;
+  for (;;) {
+    DWORD lockval = oldval | SRW_LOCKED;
+    DWORD val = (DWORD)interlocked_cmpxchg_ptr(&srwlock->Ptr, (void*)lockval, (void*)oldval);
+    if (val & SRW_LOCKED) {
+      // other thread holding lock
+      struct timespec ts;
+      ts.tv_sec = 0;
+      ts.tv_nsec = 1000;
+      futex_wait((int*)&srwlock->Ptr, val, &ts);
+      continue;
+    }
+    if (val != oldval) {
+      oldval = val & ~SRW_LOCKED;
+      continue;
+    }
+    TRACE("lock->(%p %p)\n", srwlock, srwlock->Ptr);
+    return;
+  }
+}
+
+void unlock_srwlock(PSRWLOCK srwlock) {
+  TRACE("unlock (%p, %p)\n", srwlock, srwlock->Ptr);
+  DWORD oldval = (DWORD)srwlock->Ptr;
+  DWORD unlockval = oldval & ~SRW_LOCKED;
+  interlocked_cmpxchg_ptr(&srwlock->Ptr, (void*)unlockval, (void*)oldval);
+  TRACE("unlock-> (%p, %p)\n", srwlock, srwlock->Ptr);
+  futex_wake((int*)&srwlock->Ptr, 1);
+}
+
+void wait_srwlock(PSRWLOCK srwlock) {
+  TRACE("wait (%p, %p)\n", srwlock, srwlock->Ptr);
+  DWORD val = 0;
+  unlock_srwlock(srwlock);
+  val = (DWORD)interlocked_cmpxchg_ptr(&srwlock->Ptr, (void*)0, (void*)0);
+  struct timespec ts;
+  ts.tv_sec = 0;
+  ts.tv_nsec = 100 * 1000 * 1000;
+  futex_wait((int*)&srwlock->Ptr, val, &ts);
+  lock_srwlock(srwlock);
+}
+
+void wake_srwlock(PSRWLOCK srwlock) {
+  TRACE("wake (%p, %p)\n", srwlock, srwlock->Ptr);
+  DWORD val = (DWORD)srwlock->Ptr;
+  futex_wake((int*)&srwlock->Ptr, 32);  // TODO(ukai): # of waiting threads?
+}
+
+void srwlock_write_active(PSRWLOCK srwlock, BOOL active) {
+  DWORD val = (DWORD)srwlock->Ptr;
+  if (active) {
+    val |= SRW_WRITE_ACTIVE;
+  } else {
+    val &= ~SRW_WRITE_ACTIVE;
+  }
+  TRACE("srwlock write (%p, %p->%p)\n", srwlock, srwlock->Ptr, val);
+  srwlock->Ptr = (void*)val;
+}
+
+BOOL srwlock_write_locked(PSRWLOCK srwlock) {
+  DWORD val = (DWORD)srwlock->Ptr;
+  return (val & SRW_WRITE_ACTIVE) != 0;
+}
+
+void srwlock_read_active(PSRWLOCK srwlock, BOOL active) {
+  DWORD val = (DWORD)srwlock->Ptr;
+  DWORD readers = val & SRW_READERS_ACTIVE_MASK;
+  val &= ~SRW_READERS_ACTIVE_MASK;
+  if (active) {
+    ++readers;
+  } else {
+    --readers;
+  }
+  val |= (readers & SRW_READERS_ACTIVE_MASK);
+  TRACE("srwlock read (%p, %p->%p)\n", srwlock, srwlock->Ptr, val);
+  srwlock->Ptr = (void*)val;
+}
+
+int srwlock_read_locked(PSRWLOCK srwlock) {
+  DWORD val = (DWORD)srwlock->Ptr;
+  return (val & SRW_READERS_ACTIVE_MASK);
+}
+
+#endif
+
+/***********************************************************************
+ *              InitializeSRWLock (KERNEL32.@)
+ */
+VOID WINAPI InitializeSRWLock( PSRWLOCK srwlock )
+{
+  TRACE("(%p)\n", srwlock);
+  srwlock->Ptr = 0;
+  TRACE("(%p, %p) initialized\n", srwlock, srwlock->Ptr);
+}
+
+/***********************************************************************
+ *              AcquireSRWLockExclusive (KERNEL32.@)
+ */
+VOID WINAPI AcquireSRWLockExclusive( PSRWLOCK srwlock )
+{
+#ifndef __linux__
+    FIXME( "(%p): stub\n", srwlock );
+#else
+    TRACE( "(%p)\n", srwlock );
+    lock_srwlock(srwlock);
+    for (;;) {
+      if (srwlock_write_locked(srwlock) || srwlock_read_locked(srwlock) > 0) {
+        TRACE( "(%p): wait write\n", srwlock );
+        wait_srwlock(srwlock);
+        continue;
+      }
+      srwlock_write_active(srwlock, 1);
+      break;
+    }
+    unlock_srwlock(srwlock);
+    TRACE( "->(%p): stub\n", srwlock );
+#endif
+}
+
+/***********************************************************************
+ *              ReleaseSRWLockExclusive (KERNEL32.@)
+ */
+VOID WINAPI ReleaseSRWLockExclusive( PSRWLOCK srwlock )
+{
+#ifndef __linux__
+    FIXME( "(%p): stub\n", srwlock );
+#else
+    TRACE( "(%p)\n", srwlock );
+    lock_srwlock(srwlock);
+    srwlock_write_active(srwlock, 0);
+    unlock_srwlock(srwlock);
+    wake_srwlock(srwlock);
+    TRACE( "->(%p): stub\n", srwlock );
+#endif
+}
+
+/***********************************************************************
+ *              AcquireSRWLockShared (KERNEL32.@)
+ */
+VOID WINAPI AcquireSRWLockShared( PSRWLOCK srwlock )
+{
+#ifndef __linux__
+    FIXME( "(%p): stub\n", srwlock );
+#else
+    TRACE( "(%p)\n", srwlock );
+    lock_srwlock(srwlock);
+    for (;;) {
+      if (srwlock_write_locked(srwlock)) {
+        TRACE( "(%p): wait read\n", srwlock );
+        wait_srwlock(srwlock);
+        continue;
+      }
+      srwlock_read_active(srwlock, 1);
+      break;
+    }
+    unlock_srwlock(srwlock);
+    TRACE( "->(%p): stub\n", srwlock );
+#endif
+}
+
+/***********************************************************************
+ *              ReleaseSRWLockShared (KERNEL32.@)
+ */
+VOID WINAPI ReleaseSRWLockShared( PSRWLOCK srwlock )
+{
+#ifndef __linux__
+    FIXME( "(%p): stub\n", srwlock );
+#else
+    TRACE( "(%p)\n", srwlock );
+    lock_srwlock(srwlock);
+    srwlock_read_active(srwlock, 0);
+    unlock_srwlock(srwlock);
+    wake_srwlock(srwlock);
+    TRACE( "->(%p): stub\n", srwlock );
+#endif
+}
+
diff --git a/dlls/ntdll/critsection.c b/dlls/ntdll/critsection.c
index 839c7ca..fe16738 100644
--- a/dlls/ntdll/critsection.c
+++ b/dlls/ntdll/critsection.c
@@ -510,6 +510,18 @@
     return ret;
 }
 
+static BOOL IsAllZero(const void* begin, size_t size)
+{
+    const char* m = begin;
+    int i;
+
+    for (i = 0; i < size; ++i) {
+        if (m[i] != 0)
+            return FALSE;
+    }
+
+    return TRUE;
+}
 
 /***********************************************************************
  *           RtlEnterCriticalSection   (NTDLL.@)
@@ -530,6 +542,25 @@
  */
 NTSTATUS WINAPI RtlEnterCriticalSection( RTL_CRITICAL_SECTION *crit )
 {
+    // VS2013 cl.exe calls this with zero cleared crit.
+    // As far as we examined, this does not happen in real Windows.
+    // So maybe there is a wine bug that causes this. However, I have no idea
+    // about what causes this.
+    // Let's allow it to enter critical section for workaround.
+    if (IsAllZero(crit, sizeof(RTL_CRITICAL_SECTION))) {
+        if (interlocked_cmpxchg(&crit->SpinCount, 4000, 0) == 0) {
+            // OK. SpinCount was 0, and now 4000.
+            crit->LockCount = -1;
+        }
+
+        // When interlocked_cmpxchg was failed, someone changed SpinCount
+        // after IsAllZero(). With this workaround, someone will change or
+        // has changed crit->LockCount to -1. Leaving LockCount as is so that
+        // this thread (or the other thread) will wait for lock release.
+        // In usual case, cl.exe will return critical section with zero-cleared
+        // crit only once. So this shouldn't happen, though.
+    }
+
     if (crit->SpinCount)
     {
         ULONG count;
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 04a5b75..c7a0b7b 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1376,7 +1376,7 @@
     union file_directory_info *info;
     int i, long_len, short_len, total_len;
     struct stat st;
-    WCHAR long_nameW[MAX_DIR_ENTRY_LEN];
+    WCHAR long_nameW[MAX_DIR_ENTRY_LEN] = { (WCHAR)0 };
     WCHAR short_nameW[12];
     WCHAR *filename;
     UNICODE_STRING str;
diff --git a/include/winnls.h b/include/winnls.h
index 9ed4344..9601665 100644
--- a/include/winnls.h
+++ b/include/winnls.h
@@ -568,6 +568,10 @@
 #define LGRPID_GEORGIAN            0x10
 #define LGRPID_ARMENIAN            0x11
 
+// WINVER >= 0x0600
+#define MUI_LANGUAGE_ID            0x04
+#define MUI_LANGUAGE_NAME          0x08
+
 /* IDN defines. */
 #define IDN_ALLOW_UNASSIGNED        0x1
 #define IDN_USE_STD3_ASCII_RULES    0x2
diff --git a/loader/preloader.c b/loader/preloader.c
index f38e17a..ebf512a 100644
--- a/loader/preloader.c
+++ b/loader/preloader.c
@@ -1160,8 +1160,8 @@
 {
     long i, *pargc;
     char **argv, **p;
-    char *interp, *reserve = NULL;
-    struct wld_auxv new_av[12], delete_av[3], *av;
+    char *interp = NULL, *reserve = NULL;
+    ElfW(auxv_t) new_av[12], delete_av[3], *av;
     struct wld_link_map main_binary_map, ld_so_map;
     struct wine_preload_info **wine_main_preload_info;
 
@@ -1176,7 +1176,9 @@
     while (*p)
     {
         static const char res[] = "WINEPRELOADRESERVE=";
+        static const char elfld[] = "WINEELFLOADER=";
         if (!wld_strncmp( *p, res, sizeof(res)-1 )) reserve = *p + sizeof(res) - 1;
+        if (!wld_strncmp( *p, elfld, sizeof(elfld)-1 )) interp = *p + sizeof(elfld) - 1;
         p++;
     }
 
@@ -1224,7 +1226,8 @@
     map_so_lib( argv[1], &main_binary_map );
 
     /* load the ELF interpreter */
-    interp = (char *)main_binary_map.l_addr + main_binary_map.l_interp;
+    if (!interp)
+      interp = (char *)main_binary_map.l_addr + main_binary_map.l_interp;
     map_so_lib( interp, &ld_so_map );
 
     /* store pointer to the preload info into the appropriate main binary variable */
diff --git a/server/main.c b/server/main.c
index 7aed338..2ec98b9 100644
--- a/server/main.c
+++ b/server/main.c
@@ -41,7 +41,7 @@
 /* command-line options */
 int debug_level = 0;
 int foreground = 0;
-timeout_t master_socket_timeout = 3 * -TICKS_PER_SEC;  /* master socket timeout, default is 3 seconds */
+timeout_t master_socket_timeout = 0;
 const char *server_argv0;
 
 /* parse-line args */