rv = CallQueryInterface(appDir, &aResult->directory); if (NS_FAILED(rv)) return 2;
static int LoadAppData(const char* appDataFile, nsXREAppData* aResult){  static char vendor[256], name[256], version[32], buildID[32], appID[256], copyright[512];    nsresult rv;  nsCOMPtr<nsILocalFile> lf;  XRE_GetFileFromPath(appDataFile, getter_AddRefs(lf));  if (!lf)    return 2;  rv = lf->GetParent(&aResult->appDir);  if (NS_FAILED(rv))    return 2;    nsINIParser parser;  rv = parser.Init(lf)  if (NS_FAILED(rv))    return 2;  // Gecko version checking  //  // TODO: If these version checks fail, then look for a compatible XULRunner  //       version on the system, and launch it instead.  char gkVersion[32];  rv = parser.GetString("Gecko", "MinVersion", gkVersion, sizeof(gkVersion));  if (NS_FAILED(rv) || !CheckMinVersion(gkVersion)) {    Output(PR_TRUE, "Error: Gecko MinVersion requirement not met.\n");    return 1;  }  rv = parser.GetString("Gecko", "MaxVersion", gkVersion, sizeof(gkVersion));  if (NS_SUCCEEDED(rv) && !CheckMaxVersion(gkVersion)) {    Output(PR_TRUE, "Error: Gecko MaxVersion requirement not met.\n");    return 1;  }  PRUint32 i;  // Read string-valued fields  const struct {    const char *key;    char      **fill;    char       *buf;    size_t      bufLen;    PRBool      required;  } string_fields[] = {    { "Vendor",    &aResult->vendor,    vendor,    sizeof(vendor),    PR_FALSE },    { "Name",      &aResult->name,      name,      sizeof(name),      PR_TRUE  },    { "Version",   &aResult->version,   version,   sizeof(version),   PR_FALSE },    { "BuildID",   &aResult->buildID,   buildID,   sizeof(buildID),   PR_TRUE  },    { "ID",        &aResult->ID,        appID,     sizeof(appID),     PR_FALSE },    { "Copyright", &aResult->copyright, copyright, sizeof(copyright), PR_FALSE }  };  for (i = 0; i < NS_ARRAY_LENGTH(string_fields); ++i) {    rv = parser.GetString("App", string_fields[i].key, string_fields[i].buf,                          string_fields[i].bufLen);    if (NS_SUCCEEDED(rv)) {      *fill = string_fields[i].buf;    }    else if (string_fields[i].required) {      Output(PR_TRUE, "Error: %x: No \"%s\" field.\n",	     rv, string_fields[i].key);      return 1;    }  }  // Read boolean-valued fields  const struct {    const char* key;    PRUint32 flag;  } boolean_fields[] = {    { "EnableProfileMigrator",  NS_XRE_ENABLE_PROFILE_MIGRATOR  },    { "EnableExtensionManager", NS_XRE_ENABLE_EXTENSION_MANAGER }  };  char buf[6]; // large enough to hold "false"  aResult->flags = 0;  for (i = 0; i < NS_ARRAY_LENGTH(boolean_fields); ++i) {    rv = parser.GetString("XRE", boolean_fields[i].key, buf, sizeof(buf));    // accept a truncated result since we are only interested in the    // first character.  this is designed to allow the possibility of    // expanding these boolean attributes to express additional options.    if ((NS_SUCCEEDED(rv) || rv == NS_ERROR_LOSS_OF_SIGNIFICANT_DATA) &&        (buf[0] == '1' || buf[0] == 't' || buf[0] == 'T')) {      aResult->flags |= boolean_fields[i].flag;    }  } #ifdef DEBUG  printf("---------------------------------------------------------\n");  printf("     Vendor %s\n", aResult->appVendor);  printf("       Name %s\n", aResult->appName);  printf("    Version %s\n", aResult->appVersion);  printf("    BuildID %s\n", aResult->appBuildID);  printf("  Copyright %s\n", aResult->copyright);  printf("      Flags %08x\n", aResult->flags);  printf("---------------------------------------------------------\n");#endif  return 0;}