示例#1
0
/* create a desktop object */
static struct desktop *create_desktop( const struct unicode_str *name, unsigned int attr,
                                       unsigned int flags, struct winstation *winstation )
{
    struct desktop *desktop;

    if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) ))  /* no backslash allowed in name */
    {
        set_error( STATUS_INVALID_PARAMETER );
        return NULL;
    }

    if ((desktop = create_named_object( winstation->desktop_names, &desktop_ops, name, attr )))
    {
        if (get_error() != STATUS_OBJECT_NAME_EXISTS)
        {
            /* initialize it if it didn't already exist */
            desktop->flags = flags;
            desktop->winstation = (struct winstation *)grab_object( winstation );
            desktop->top_window = NULL;
            desktop->msg_window = NULL;
            desktop->global_hooks = NULL;
            desktop->close_timeout = NULL;
            desktop->foreground_input = NULL;
            desktop->users = 0;
            memset( &desktop->cursor, 0, sizeof(desktop->cursor) );
            memset( desktop->keystate, 0, sizeof(desktop->keystate) );
            list_add_tail( &winstation->desktops, &desktop->entry );
            list_init( &desktop->hotkeys );
        }
    }
    return desktop;
}
示例#2
0
/* create a winstation object */
static struct winstation *create_winstation( struct directory *root, const struct unicode_str *name,
                                             unsigned int attr, unsigned int flags )
{
    struct winstation *winstation;

    if (memchrW( name->str, '\\', name->len / sizeof(WCHAR) ))  /* no backslash allowed in name */
    {
        set_error( STATUS_INVALID_PARAMETER );
        return NULL;
    }

    if ((winstation = create_named_object_dir( root, name, attr, &winstation_ops )))
    {
        if (get_error() != STATUS_OBJECT_NAME_EXISTS)
        {
            /* initialize it if it didn't already exist */
            winstation->flags = flags;
            winstation->clipboard = NULL;
            winstation->atom_table = NULL;
            list_add_tail( &winstation_list, &winstation->entry );
            list_init( &winstation->desktops );
            if (!(winstation->desktop_names = create_namespace( 7 )))
            {
                release_object( winstation );
                return NULL;
            }
        }
    }
    return winstation;
}
示例#3
0
static struct display_mode_descriptor* create_original_display_mode_descriptor(CGDirectDisplayID displayID)
{
    static const char display_key_format[] = "Software\\Wine\\Mac Driver\\Initial Display Mode\\Display 0x%08x";
    struct display_mode_descriptor* ret = NULL;
    struct display_mode_descriptor* desc;
    char display_key[sizeof(display_key_format) + 10];
    HKEY hkey;
    DWORD type, size;
    DWORD refresh100;
    WCHAR* pixel_encoding = NULL, *end;

    init_original_display_mode();

    snprintf(display_key, sizeof(display_key), display_key_format, CGDisplayUnitNumber(displayID));
    /* @@ Wine registry key: HKLM\Software\Wine\Mac Driver\Initial Display Mode\Display 0xnnnnnnnn */
    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, display_key, 0, KEY_READ, &hkey))
        return NULL;

    desc = HeapAlloc(GetProcessHeap(), 0, sizeof(*desc));
    desc->pixel_encoding = NULL;

    if (!read_dword(hkey, "Width", &desc->width) ||
            !read_dword(hkey, "Height", &desc->height) ||
            !read_dword(hkey, "RefreshRateTimes100", &refresh100) ||
            !read_dword(hkey, "IOFlags", &desc->io_flags))
        goto done;
    if (refresh100)
        desc->refresh = refresh100 / 100.0;
    else
        desc->refresh = 60;

    if (!read_dword(hkey, "PixelWidth", &desc->pixel_width) ||
            !read_dword(hkey, "PixelHeight", &desc->pixel_height))
    {
        desc->pixel_width = desc->width;
        desc->pixel_height = desc->height;
    }

    size = 0;
    if (RegQueryValueExW(hkey, pixelencodingW, 0, &type, NULL, &size) || type != REG_SZ)
        goto done;
    pixel_encoding = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
    if (RegQueryValueExW(hkey, pixelencodingW, 0, &type, (BYTE*)pixel_encoding, &size) || type != REG_SZ)
        goto done;
    if ((end = memchrW(pixel_encoding, 0, size)))
        size = end - pixel_encoding;
    desc->pixel_encoding = CFStringCreateWithCharacters(NULL, (const UniChar*)pixel_encoding, size);

    ret = desc;

done:
    if (!ret)
        free_display_mode_descriptor(desc);
    HeapFree(GetProcessHeap(), 0, pixel_encoding);
    RegCloseKey(hkey);
    return ret;
}
示例#4
0
/* convert data to ASCII, unless it looks like it's not in Unicode format */
static HDDEDATA map_W_to_A( DWORD instance, void *ptr, DWORD size )
{
    HDDEDATA ret;
    DWORD len;
    const WCHAR *end;

    if (data_looks_unicode( ptr, size ))
    {
        size /= sizeof(WCHAR);
        if ((end = memchrW( ptr, 0, size ))) size = end + 1 - (const WCHAR *)ptr;
        len = WideCharToMultiByte( CP_ACP, 0, ptr, size, NULL, 0, NULL, NULL );
        ret = DdeCreateDataHandle( instance, NULL, len, 0, 0, CF_TEXT, 0);
        WideCharToMultiByte( CP_ACP, 0, ptr, size, (char *)DdeAccessData(ret, NULL), len, NULL, NULL );
    }
    else ret = DdeCreateDataHandle( instance, ptr, size, 0, 0, CF_TEXT, 0 );

    return ret;
}
示例#5
0
/****************************************************************************
 * WCMD_HandleTildaModifiers
 *
 * Handle the ~ modifiers when expanding %0-9 or (%a-z in for command)
 *    %~xxxxxV  (V=0-9 or A-Z)
 * Where xxxx is any combination of:
 *    ~ - Removes quotes
 *    f - Fully qualified path (assumes current dir if not drive\dir)
 *    d - drive letter
 *    p - path
 *    n - filename
 *    x - file extension
 *    s - path with shortnames
 *    a - attributes
 *    t - date/time
 *    z - size
 *    $ENVVAR: - Searches ENVVAR for (contents of V) and expands to fully
 *                   qualified path
 *
 *  To work out the length of the modifier:
 *
 *  Note: In the case of %0-9 knowing the end of the modifier is easy,
 *    but in a for loop, the for end WCHARacter may also be a modifier
 *    eg. for %a in (c:\a.a) do echo XXX
 *             where XXX = %~a    (just ~)
 *                         %~aa   (~ and attributes)
 *                         %~aaxa (~, attributes and extension)
 *                   BUT   %~aax  (~ and attributes followed by 'x')
 *
 *  Hence search forwards until find an invalid modifier, and then
 *  backwards until find for variable or 0-9
 */
void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable, WCHAR *forValue, BOOL justFors) {

#define NUMMODIFIERS 11
  static const WCHAR validmodifiers[NUMMODIFIERS] = {
        '~', 'f', 'd', 'p', 'n', 'x', 's', 'a', 't', 'z', '$'
  };
  static const WCHAR space[] = {' ', '\0'};

  WIN32_FILE_ATTRIBUTE_DATA fileInfo;
  WCHAR  outputparam[MAX_PATH];
  WCHAR  finaloutput[MAX_PATH];
  WCHAR  fullfilename[MAX_PATH];
  WCHAR  thisoutput[MAX_PATH];
  WCHAR  *pos            = *start+1;
  WCHAR  *firstModifier  = pos;
  WCHAR  *lastModifier   = NULL;
  int   modifierLen     = 0;
  BOOL  finished        = FALSE;
  int   i               = 0;
  BOOL  exists          = TRUE;
  BOOL  skipFileParsing = FALSE;
  BOOL  doneModifier    = FALSE;

  /* Search forwards until find invalid character modifier */
  while (!finished) {

    /* Work on the previous character */
    if (lastModifier != NULL) {

      for (i=0; i<NUMMODIFIERS; i++) {
        if (validmodifiers[i] == *lastModifier) {

          /* Special case '$' to skip until : found */
          if (*lastModifier == '$') {
            while (*pos != ':' && *pos) pos++;
            if (*pos == 0x00) return; /* Invalid syntax */
            pos++;                    /* Skip ':'       */
          }
          break;
        }
      }

      if (i==NUMMODIFIERS) {
        finished = TRUE;
      }
    }

    /* Save this one away */
    if (!finished) {
      lastModifier = pos;
      pos++;
    }
  }

  while (lastModifier > firstModifier) {
    WINE_TRACE("Looking backwards for parameter id: %s / %s\n",
               wine_dbgstr_w(lastModifier), wine_dbgstr_w(forVariable));

    if (!justFors && context && (*lastModifier >= '0' || *lastModifier <= '9')) {
      /* Its a valid parameter identifier - OK */
      break;

    } else if (forVariable && *lastModifier == *(forVariable+1)) {
      /* Its a valid parameter identifier - OK */
      break;

    } else {
      lastModifier--;
    }
  }
  if (lastModifier == firstModifier) return; /* Invalid syntax */

  /* Extract the parameter to play with */
  if ((*lastModifier >= '0' && *lastModifier <= '9')) {
    strcpyW(outputparam, WCMD_parameter (context -> command,
                 *lastModifier-'0' + context -> shift_count[*lastModifier-'0'], NULL));
  } else {
    strcpyW(outputparam, forValue);
  }

  /* So now, firstModifier points to beginning of modifiers, lastModifier
     points to the variable just after the modifiers. Process modifiers
     in a specific order, remembering there could be duplicates           */
  modifierLen = lastModifier - firstModifier;
  finaloutput[0] = 0x00;

  /* Useful for debugging purposes: */
  /*printf("Modifier string '%*.*s' and variable is %c\n Param starts as '%s'\n",
             (modifierLen), (modifierLen), firstModifier, *lastModifier,
             outputparam);*/

  /* 1. Handle '~' : Strip surrounding quotes */
  if (outputparam[0]=='"' &&
      memchrW(firstModifier, '~', modifierLen) != NULL) {
    int len = strlenW(outputparam);
    if (outputparam[len-1] == '"') {
        outputparam[len-1]=0x00;
        len = len - 1;
    }
    memmove(outputparam, &outputparam[1], (len * sizeof(WCHAR))-1);
  }

  /* 2. Handle the special case of a $ */
  if (memchrW(firstModifier, '$', modifierLen) != NULL) {
    /* Special Case: Search envar specified in $[envvar] for outputparam
       Note both $ and : are guaranteed otherwise check above would fail */
    WCHAR *start = strchrW(firstModifier, '$') + 1;
    WCHAR *end   = strchrW(firstModifier, ':');
    WCHAR env[MAX_PATH];
    WCHAR fullpath[MAX_PATH];

    /* Extract the env var */
    memcpy(env, start, (end-start) * sizeof(WCHAR));
    env[(end-start)] = 0x00;

    /* If env var not found, return empty string */
    if ((GetEnvironmentVariable(env, fullpath, MAX_PATH) == 0) ||
        (SearchPath(fullpath, outputparam, NULL,
                    MAX_PATH, outputparam, NULL) == 0)) {
      finaloutput[0] = 0x00;
      outputparam[0] = 0x00;
      skipFileParsing = TRUE;
    }
  }

  /* After this, we need full information on the file,
    which is valid not to exist.  */
  if (!skipFileParsing) {
    if (GetFullPathName(outputparam, MAX_PATH, fullfilename, NULL) == 0)
      return;

    exists = GetFileAttributesExW(fullfilename, GetFileExInfoStandard,
                                  &fileInfo);

    /* 2. Handle 'a' : Output attributes */
    if (exists &&
        memchrW(firstModifier, 'a', modifierLen) != NULL) {

      WCHAR defaults[] = {'-','-','-','-','-','-','-','-','-','\0'};
      doneModifier = TRUE;
      strcpyW(thisoutput, defaults);
      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        thisoutput[0]='d';
      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
        thisoutput[1]='r';
      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE)
        thisoutput[2]='a';
      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
        thisoutput[3]='h';
      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM)
        thisoutput[4]='s';
      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED)
        thisoutput[5]='c';
      /* FIXME: What are 6 and 7? */
      if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
        thisoutput[8]='l';
      strcatW(finaloutput, thisoutput);
    }

    /* 3. Handle 't' : Date+time */
    if (exists &&
        memchrW(firstModifier, 't', modifierLen) != NULL) {

      SYSTEMTIME systime;
      int datelen;

      doneModifier = TRUE;
      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);

      /* Format the time */
      FileTimeToSystemTime(&fileInfo.ftLastWriteTime, &systime);
      GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime,
                        NULL, thisoutput, MAX_PATH);
      strcatW(thisoutput, space);
      datelen = strlenW(thisoutput);
      GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &systime,
                        NULL, (thisoutput+datelen), MAX_PATH-datelen);
      strcatW(finaloutput, thisoutput);
    }

    /* 4. Handle 'z' : File length */
    if (exists &&
        memchrW(firstModifier, 'z', modifierLen) != NULL) {
      /* FIXME: Output full 64 bit size (sprintf does not support I64 here) */
      ULONG/*64*/ fullsize = /*(fileInfo.nFileSizeHigh << 32) +*/
                                  fileInfo.nFileSizeLow;
      static const WCHAR fmt[] = {'%','u','\0'};

      doneModifier = TRUE;
      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
      wsprintf(thisoutput, fmt, fullsize);
      strcatW(finaloutput, thisoutput);
    }

    /* 4. Handle 's' : Use short paths (File doesn't have to exist) */
    if (memchrW(firstModifier, 's', modifierLen) != NULL) {
      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
      /* Don't flag as doneModifier - %~s on its own is processed later */
      GetShortPathName(outputparam, outputparam,
                       sizeof(outputparam)/sizeof(outputparam[0]));
    }

    /* 5. Handle 'f' : Fully qualified path (File doesn't have to exist) */
    /*      Note this overrides d,p,n,x                                 */
    if (memchrW(firstModifier, 'f', modifierLen) != NULL) {
      doneModifier = TRUE;
      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
      strcatW(finaloutput, fullfilename);
    } else {

      WCHAR drive[10];
      WCHAR dir[MAX_PATH];
      WCHAR fname[MAX_PATH];
      WCHAR ext[MAX_PATH];
      BOOL doneFileModifier = FALSE;

      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);

      /* Split into components */
      WCMD_splitpath(fullfilename, drive, dir, fname, ext);

      /* 5. Handle 'd' : Drive Letter */
      if (memchrW(firstModifier, 'd', modifierLen) != NULL) {
        strcatW(finaloutput, drive);
        doneModifier = TRUE;
        doneFileModifier = TRUE;
      }

      /* 6. Handle 'p' : Path */
      if (memchrW(firstModifier, 'p', modifierLen) != NULL) {
        strcatW(finaloutput, dir);
        doneModifier = TRUE;
        doneFileModifier = TRUE;
      }

      /* 7. Handle 'n' : Name */
      if (memchrW(firstModifier, 'n', modifierLen) != NULL) {
        strcatW(finaloutput, fname);
        doneModifier = TRUE;
        doneFileModifier = TRUE;
      }

      /* 8. Handle 'x' : Ext */
      if (memchrW(firstModifier, 'x', modifierLen) != NULL) {
        strcatW(finaloutput, ext);
        doneModifier = TRUE;
        doneFileModifier = TRUE;
      }

      /* If 's' but no other parameter, dump the whole thing */
      if (!doneFileModifier &&
          memchrW(firstModifier, 's', modifierLen) != NULL) {
        doneModifier = TRUE;
        if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
        strcatW(finaloutput, outputparam);
      }
    }
  }

  /* If No other modifier processed,  just add in parameter */
  if (!doneModifier) strcpyW(finaloutput, outputparam);

  /* Finish by inserting the replacement into the string */
  pos = WCMD_strdupW(lastModifier+1);
  strcpyW(*start, finaloutput);
  strcatW(*start, pos);
  free(pos);
}
示例#6
0
/******************************************************************
 *		RtlExpandEnvironmentStrings_U (NTDLL.@)
 *
 */
NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PCWSTR renv, const UNICODE_STRING* us_src,
                                              PUNICODE_STRING us_dst, PULONG plen)
{
    DWORD src_len, len, count, total_size = 1;  /* 1 for terminating '\0' */
    LPCWSTR     env, src, p, var;
    LPWSTR      dst;

    src = us_src->Buffer;
    src_len = us_src->Length / sizeof(WCHAR);
    count = us_dst->MaximumLength / sizeof(WCHAR);
    dst = count ? us_dst->Buffer : NULL;

    if (!renv)
    {
        RtlAcquirePebLock();
        env = NtCurrentTeb()->Peb->ProcessParameters->Environment;
    }
    else env = renv;

    while (src_len)
    {
        if (*src != '%')
        {
            if ((p = memchrW( src, '%', src_len ))) len = p - src;
            else len = src_len;
            var = src;
            src += len;
            src_len -= len;
        }
        else  /* we are at the start of a variable */
        {
            if ((p = memchrW( src + 1, '%', src_len - 1 )))
            {
                len = p - src - 1;  /* Length of the variable name */
                if ((var = ENV_FindVariable( env, src + 1, len )))
                {
                    src += len + 2;  /* Skip the variable name */
                    src_len -= len + 2;
                    len = strlenW(var);
                }
                else
                {
                    var = src;  /* Copy original name instead */
                    len += 2;
                    src += len;
                    src_len -= len;
                }
            }
            else  /* unfinished variable name, ignore it */
            {
                var = src;
                len = src_len;  /* Copy whole string */
                src += len;
                src_len = 0;
            }
        }
        total_size += len;
        if (dst)
        {
            if (count < len) len = count;
            memcpy(dst, var, len * sizeof(WCHAR));
            count -= len;
            dst += len;
        }
    }

    if (!renv) RtlReleasePebLock();

    /* Null-terminate the string */
    if (dst && count) *dst = '\0';

    us_dst->Length = (dst) ? (dst - us_dst->Buffer) * sizeof(WCHAR) : 0;
    if (plen) *plen = total_size * sizeof(WCHAR);

    return (count) ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL;
}
示例#7
0
static void msvcrt_search_executable(const MSVCRT_wchar_t *name, MSVCRT_wchar_t *fullname, int use_path)
{
  static const MSVCRT_wchar_t path[] = {'P','A','T','H',0};
  static const MSVCRT_wchar_t suffix[][5] =
    {{'.','c','o','m',0}, {'.','e','x','e',0}, {'.','b','a','t',0}, {'.','c','m','d',0}};

  MSVCRT_wchar_t buffer[MAX_PATH];
  const MSVCRT_wchar_t *env, *p;
  unsigned int i, name_len, path_len;
  int extension = 1;

  *fullname = '\0';
  msvcrt_set_errno(ERROR_FILE_NOT_FOUND);

  p = memchrW(name, '\0', MAX_PATH);
  if (!p) p = name + MAX_PATH - 1;
  name_len = p - name;

  /* FIXME extra-long names are silently truncated */
  memcpy(buffer, name, name_len * sizeof(MSVCRT_wchar_t));
  buffer[name_len] = '\0';

  /* try current dir first */
  if (GetFileAttributesW(buffer) != INVALID_FILE_ATTRIBUTES)
  {
    strcpyW(fullname, buffer);
    return;
  }

  for (p--; p >= name; p--)
    if (*p == '\\' || *p == '/' || *p == ':' || *p == '.') break;

  /* if there's no extension, try some well-known extensions */
  if ((p < name || *p != '.') && name_len <= MAX_PATH - 5)
  {
    for (i = 0; i < 4; i++)
    {
      memcpy(buffer + name_len, suffix[i], 5 * sizeof(MSVCRT_wchar_t));
      if (GetFileAttributesW(buffer) != INVALID_FILE_ATTRIBUTES)
      {
        strcpyW(fullname, buffer);
        return;
      }
    }
    extension = 0;
  }

  if (!use_path || !(env = _wgetenv(path))) return;

  /* now try search path */
  do
  {
    p = env;
    while (*p && *p != ';') p++;
    if (p == env) return;

    path_len = p - env;
    if (path_len + name_len <= MAX_PATH - 2)
    {
      memcpy(buffer, env, path_len * sizeof(MSVCRT_wchar_t));
      if (buffer[path_len] != '/' || buffer[path_len] != '\\')
      {
        buffer[path_len++] = '\\';
        buffer[path_len] = '\0';
      }
      else buffer[path_len] = '\0';

      strcatW(buffer, name);
      if (GetFileAttributesW(buffer) != INVALID_FILE_ATTRIBUTES)
      {
        strcpyW(fullname, buffer);
        return;
      }
    }
    /* again, if there's no extension, try some well-known extensions */
    if (!extension && path_len + name_len <= MAX_PATH - 5)
    {
      for (i = 0; i < 4; i++)
      {
        memcpy(buffer + path_len + name_len, suffix[i], 5 * sizeof(MSVCRT_wchar_t));
        if (GetFileAttributesW(buffer) != INVALID_FILE_ATTRIBUTES)
        {
          strcpyW(fullname, buffer);
          return;
        }
      }
    }
    env = *p ? p + 1 : p;
  } while(1);
}