DWORD _CeGetFileSize(
		HANDLE hFile,
		LPDWORD lpFileSizeHigh)
{
	RapiContext* context = rapi_context_current();
	DWORD size = BAD_FILE_SIZE;

	rapi_context_begin_command(context, 0x1d);
	rapi_buffer_write_uint32(context->send_buffer, (uint32_t)hFile);
	rapi_buffer_write_optional_out(context->send_buffer,
			lpFileSizeHigh, sizeof(*lpFileSizeHigh));

	if ( !rapi_context_call(context) )
		return BAD_FILE_SIZE;

	if ( !rapi_buffer_read_uint32(context->recv_buffer, &context->last_error) )
		return BAD_FILE_SIZE;
	synce_trace("last_error = %i", context->last_error);

	if ( !rapi_buffer_read_uint32(context->recv_buffer, &size) )
		return BAD_FILE_SIZE;

	if ( !rapi_buffer_read_optional_uint32(context->recv_buffer, lpFileSizeHigh) )
		return BAD_FILE_SIZE;

	return size;
}
Example #2
0
static bool recurrence_set_exceptions(RRA_RecurrencePattern* pattern, RRA_MdirLineVector* exdates)
{
  unsigned i;
  bool success = false;
  RRA_Exceptions* exceptions = pattern->exceptions;

  /* TODO: support more than one exception per EXDATE line */

  rra_exceptions_make_reservation(exceptions, exdates->used);

  for (i = 0; i < exdates->used; i++)
  {
    RRA_Exception* exception = rra_exceptions_item(exceptions, i);
    struct tm exdate;

    if (!parser_datetime_to_struct(exdates->items[i]->values[0], &exdate, NULL))
      goto exit;
    
    exception->deleted = true;

    /* Only date */
    exception->date = rra_minutes_from_struct(&exdate);

    /* Date and time */
    exdate.tm_min = pattern->start_minute;
    exception->original_time = rra_minutes_from_struct(&exdate);
    synce_trace("exception->original_time: %s", asctime(&exdate));
  }

  success = true;

exit:
  return success;
}
Example #3
0
static bool recurrence_initialize_rrule_ical(const char* str, RRule* rrule)
{
  int i;
  char** strv = strsplit(str, ';');

  rrule->interval = 1;

  for (i = 0; strv[i]; i++)
  {
    char** pair = strsplit(strv[i], '=');
    if (!pair[0] || !pair[1])
    {
      synce_warning("Invalid rrule part: '%s'", strv[i]);
      continue;
    }

    synce_trace("RRULE part: key=%s, value=%s", 
        pair[0], pair[1]);

    if (STR_EQUAL(pair[0], "BYDAY"))
      replace_string_with_copy(&rrule->byday, pair[1]);
    else if (STR_EQUAL(pair[0], "BYMONTH"))
      rrule->bymonth = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "BYMONTHDAY"))
      rrule->bymonthday = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "BYSETPOS"))
      rrule->bysetpos = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "COUNT"))
      rrule->count = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "FREQ"))
      {
	if (STR_EQUAL(pair[1], "DAILY"))
	  rrule->freq = RRuleDaily;
	else if (STR_EQUAL(pair[1], "WEEKLY"))
	  rrule->freq = RRuleWeekly;
	else if (STR_EQUAL(pair[1], "MONTHLY"))
	  rrule->freq = RRuleMonthly;
	else if (STR_EQUAL(pair[1], "YEARLY"))
	  rrule->freq = RRuleYearly;
	else
	  synce_error("Unexpected frequencey in RRULE '%s'", str);
      }
    else if (STR_EQUAL(pair[0], "INTERVAL"))
      rrule->interval = atoi(pair[1]);
    else if (STR_EQUAL(pair[0], "UNTIL"))
      replace_string_with_copy(&rrule->until, pair[1]);
    else
      synce_warning("Unhandled part of RRULE: '%s'", strv[i]);

    strv_free(pair);
  }
  
  strv_free(strv);
  return true;
}
Example #4
0
bool generator_set_data(Generator* self, const uint8_t* data, size_t data_size)/*{{{*/
{
  bool success = false;

  if (!data)
  {
    synce_error("RRA Calendar data is NULL");
    goto exit;
  }

  if (data_size < 8)
  {
    synce_error("Invalid data size for RRA calendar data");
    goto exit;
  }

  self->propval_count = letoh32(*(uint32_t*)(data + 0));
  synce_trace("RRA calendar data field count: %i", self->propval_count);

  if (0 == self->propval_count)
  {
    synce_error("No fields in RRA calendar record!");
    goto exit;
  } 
	
  if (self->propval_count > MAX_PROPVAL_COUNT)
  {
    synce_error("Too many fields in RRA calendar record");
    goto exit;
  }

  self->propvals = (CEPROPVAL*)malloc(sizeof(CEPROPVAL) * self->propval_count);

  if (!dbstream_to_propvals(data + 8, self->propval_count, self->propvals))
  {
    synce_error("Failed to convert RRA calendar database stream");
    goto exit;
  }

  success = true;

exit:
  return success;
}/*}}}*/
Example #5
0
static void recurrence_append_until_or_count_ical(
    char* buffer, 
    size_t size, 
    RRA_RecurrencePattern* pattern)
{
  switch (pattern->flags & RecurrenceEndMask)
  {
    case RecurrenceEndsOnDate:
      {
        struct tm date = rra_minutes_to_struct(pattern->pattern_end_date + pattern->start_minute);
        strftime(buffer, size, ";UNTIL=%Y%m%dT%H%M%SZ", &date);
        synce_trace("UNTIL: %s", buffer);
      }
      break;

    case RecurrenceEndsAfterXOccurrences:
      snprintf(buffer, size, ";COUNT=%i", pattern->occurrences);
      break;
  }
}
BOOL _CeSHCreateShortcut(
  LPCWSTR lpszShortcut,
  LPCWSTR lpszTarget)
{
  RapiContext* context = rapi_context_current();
  BOOL return_value = 0;

  synce_trace("Creating shortcut");

  rapi_context_begin_command(context, 0x30);
  rapi_buffer_write_optional_string(context->send_buffer, lpszShortcut);
  rapi_buffer_write_optional_string(context->send_buffer, lpszTarget);

  if ( !rapi_context_call(context) )
    goto exit;

  rapi_buffer_read_uint32(context->recv_buffer, &context->last_error);
  rapi_buffer_read_uint32(context->recv_buffer, &return_value);

 exit:
  return return_value;
}
BOOL _CeSetFileAttributes(
		LPCWSTR lpFileName,
		DWORD dwFileAttributes)
{
	RapiContext* context = rapi_context_current();
	BOOL return_value = false;

	synce_trace("Setting attributes %08x", dwFileAttributes);

	rapi_context_begin_command(context, 0x04);
	rapi_buffer_write_uint32(context->send_buffer, dwFileAttributes);
	rapi_buffer_write_string(context->send_buffer, lpFileName);

	if ( !rapi_context_call(context) )
		goto exit;

	rapi_buffer_read_uint32(context->recv_buffer, &context->last_error);
	rapi_buffer_read_uint32(context->recv_buffer, &return_value);

exit:
	return return_value;
}
DWORD _CeGetSpecialFolderPath(
		int nFolder,
		DWORD nBufferLength,
		LPWSTR lpBuffer)
{
	RapiContext* context = rapi_context_current();
	size_t string_length = nBufferLength;

	rapi_context_begin_command(context, 0x44);
	rapi_buffer_write_uint32(context->send_buffer, (uint32_t)nFolder);
	rapi_buffer_write_uint32(context->send_buffer, nBufferLength);

	if ( !rapi_context_call(context) )
		return 0;

	if ( !rapi_buffer_read_uint32(context->recv_buffer, &context->last_error) )
		return 0;
	synce_trace("last_error = %i", context->last_error);

	if ( !rapi_buffer_read_string(context->recv_buffer, lpBuffer, &string_length) )
		return 0;

	return string_length;
}
BOOL _CeFindAllFiles(
		LPCWSTR szPath,
		DWORD dwFlags,
		LPDWORD lpdwFoundCount,
		LPLPCE_FIND_DATA ppFindDataArray)
{
	RapiContext* context = rapi_context_current();
	uint32_t count = 0;

	rapi_context_begin_command(context, 0x09);
	rapi_buffer_write_string(context->send_buffer, szPath);
	rapi_buffer_write_uint32(context->send_buffer, dwFlags);

	if ( !rapi_context_call(context) )
		return false;

	rapi_buffer_read_uint32(context->recv_buffer, &count);

	synce_trace("found %i files", count);

	if (count)
	{
		unsigned i;
		uint32_t name_size;
		CE_FIND_DATA* array = calloc(count, sizeof(CE_FIND_DATA));

		if (!array)
			return false;

		for (i = 0; i < count; i++)
		{
			if (dwFlags & FAF_NAME)
				rapi_buffer_read_uint32(context->recv_buffer, &name_size);

			if (dwFlags & FAF_ATTRIBUTES)
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].dwFileAttributes);

			if (dwFlags & FAF_CREATION_TIME)
			{
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].ftCreationTime.dwLowDateTime);
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].ftCreationTime.dwHighDateTime);
			}

			if (dwFlags & FAF_LASTACCESS_TIME)
			{
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].ftLastAccessTime.dwLowDateTime);
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].ftLastAccessTime.dwHighDateTime);
			}

			if (dwFlags & FAF_LASTWRITE_TIME)
			{
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].ftLastWriteTime.dwLowDateTime);
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].ftLastWriteTime.dwHighDateTime);
			}

			if (dwFlags & FAF_SIZE_HIGH)
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].nFileSizeHigh);

			if (dwFlags & FAF_SIZE_LOW)
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].nFileSizeLow);

			if (dwFlags & FAF_OID)
				rapi_buffer_read_uint32(context->recv_buffer, &array[i].dwOID);

			if (dwFlags & FAF_NAME)
			{
				rapi_buffer_read_data(context->recv_buffer, array[i].cFileName, name_size * sizeof(WCHAR) );
				synce_trace_wstr(array[i].cFileName);
			}
		}

		if (ppFindDataArray)
			*ppFindDataArray = array;

	}

	if (lpdwFoundCount)
		*lpdwFoundCount = count;

	return true;
}
Example #10
0
bool recurrence_parse_rrule(
    struct _Parser* p, 
    mdir_line* mdir_dtstart,
    mdir_line* mdir_dtend,
    mdir_line* mdir_rrule, 
    RRA_MdirLineVector* exdates,
    RRA_Timezone *tzi)
{
  bool success = false;
  RRule rrule;
  RRA_RecurrencePattern* pattern = rra_recurrence_pattern_new();

  if (!recurrence_set_dates(pattern, mdir_dtstart, mdir_dtend))
  {
    synce_error("Failed to set dates");
    goto exit;
  }

  memset(&rrule, 0, sizeof(RRule));

  bool rrule_init_result;
  if (strstr(mdir_rrule->values[0],"FREQ"))
    rrule_init_result = recurrence_initialize_rrule_ical(mdir_rrule->values[0], &rrule);
  else
    rrule_init_result = recurrence_initialize_rrule_vcal(mdir_rrule->values[0], &rrule);

  if (!rrule_init_result)
  {
    synce_error("Failed to parse RRULE '%s'", mdir_rrule->values[0]);
    goto exit;
  }

  if (rrule.freq == RRuleFreqUnknown)
  {
    synce_error("No FREQ part in RRULE '%s'", mdir_rrule->values[0]);
    goto exit;
  }

  if (rrule.freq == RRuleDaily)
  {
    pattern->recurrence_type = olRecursDaily;
    /* Convert to Daily with 24*60 times the interval (days->minutes) */
    synce_trace("Converting Interval to minutes");
    rrule.interval *= MINUTES_PER_DAY;
  }
  else if (rrule.freq == RRuleWeekly)
  {
    pattern->recurrence_type = olRecursWeekly;
    recurrence_set_days_of_week_mask(pattern, &rrule);
  }
  else if (rrule.freq == RRuleMonthly)
  {
    if (rrule.bymonthday)
    {
      pattern->recurrence_type = olRecursMonthly;
      pattern->day_of_month = rrule.bymonthday;
    }
    else if (rrule.bysetpos)
    {
      pattern->recurrence_type = olRecursMonthNth;
      pattern->instance = rrule.bysetpos;
      recurrence_set_days_of_week_mask(pattern, &rrule);
    }
    else
    {
      synce_error("Missing information for monthly recurrence in RRULE '%s'", 
          mdir_rrule->values[0]);
      goto exit;
    }
  }
  else if (rrule.freq == RRuleYearly)
  {
    /* Convert to Monthly with 12 times the interval */
    pattern->recurrence_type = olRecursMonthly;
    rrule.interval *= 12;

    if (rrule.bymonthday)
    {
      pattern->day_of_month = rrule.bymonthday;
    }
    else if (rrule.bysetpos || rrule.bymonth)
    {
      synce_error("Don't know how to handle BYSETPOS or BYMONTH in RRULE '%s'", 
          mdir_rrule->values[0]);
      goto exit;
    }
    else
    {
      /* Get BYMONTHDAY from start date */
      struct tm start_date = rra_minutes_to_struct(pattern->pattern_start_date);
      pattern->day_of_month = start_date.tm_mday;
    }
  }
  else
  {
    synce_error("Unexpected frequencey in RRULE '%s'", mdir_rrule->values[0]);
    goto exit;
  }

  pattern->interval = rrule.interval;

  if (rrule.count)
  {
    pattern->occurrences = rrule.count;
    pattern->flags |= RecurrenceEndsAfterXOccurrences;

    /* XXX calculate pattern->pattern_end_date */
    /* CE requires an explicit end date */
    /* XXX Could be problematic with leap years */
    switch (pattern->recurrence_type)
    {
      case olRecursDaily:
        synce_trace("Calculating Pattern end date for daily recursion");
        pattern->pattern_end_date = pattern->pattern_start_date + (rrule.count-1) * rrule.interval;
        break;
      case olRecursWeekly:
        /* XXX Only works for interval=1 at the moment */
        synce_trace("Calculating Pattern end date for weekly recursion");
        uint32_t count_in_mask=0;
        int i;
        for (i=0; i<7; i++)
	  if (pattern->days_of_week_mask &  (1 << i)) count_in_mask++;

        uint32_t days_to_add=((rrule.count-1)/count_in_mask)*7;
        uint32_t rest=(rrule.count-1)%count_in_mask;
	
        struct tm start_date = rra_minutes_to_struct(pattern->pattern_start_date);
        /* rotate the bitmask */
        uint32_t biased_mask = (pattern->days_of_week_mask | ((pattern->days_of_week_mask & ((1<<start_date.tm_wday)-1)) << 7))>>(start_date.tm_wday+1);
        while (rest)
	{
	  rest--;
          while (biased_mask%2==0)
	  {
            if (biased_mask==0) {synce_error("Calculation of Pattern end date failed"); goto failed;}
	    days_to_add++;
	    biased_mask>>=1;
	  }
          days_to_add++;
          biased_mask>>=1;
	}
	
	pattern->pattern_end_date = pattern->pattern_start_date + days_to_add * MINUTES_PER_DAY;

        break;
      default:
      failed:
        synce_trace("FIXME: Have to calculate Pattern end date");
    pattern->pattern_end_date = RRA_DoesNotEndDate;
  }
  }
Example #11
0
static bool recurrence_set_dates(
    RRA_RecurrencePattern* pattern, 
    mdir_line* mdir_dtstart,
    mdir_line* mdir_dtend)
{
  bool success = false;
  struct tm start_struct;
  struct tm tmp_struct;
  time_t start;
  time_t end;
  int32_t minutes = 0;
  ParserTimeFormat format = parser_get_time_format(mdir_dtstart);
  bool start_is_utc = false;
  bool end_is_utc = false;

  /* XXX timezone handling? */

  if (!parser_datetime_to_struct(mdir_dtstart->values[0], &start_struct, NULL))
    goto exit;
  if (!parser_datetime_to_unix_time(mdir_dtstart->values[0], &start, &start_is_utc))
    goto exit;
  if (!parser_datetime_to_unix_time(mdir_dtend->values[0], &end, &end_is_utc))
    goto exit;

#if VERBOSE
  synce_trace("start is %s", asctime(&start_struct));
  synce_trace("start is utc: %i, end is utc: %i", start_is_utc, end_is_utc);
#endif

  tmp_struct = start_struct;
  tmp_struct.tm_sec = 0;
  tmp_struct.tm_min = 0;
  tmp_struct.tm_hour = 0;
  pattern->pattern_start_date = rra_minutes_from_struct(&tmp_struct);

  pattern->start_minute = start_struct.tm_hour * 60 + start_struct.tm_min;

  switch (format)
  {
    case PARSER_TIME_FORMAT_UNKNOWN:
      goto exit;

    case PARSER_TIME_FORMAT_DATE_AND_TIME:
      minutes = (end - start) / 60;
      break;

    case PARSER_TIME_FORMAT_ONLY_DATE:
      minutes = (end - start - SECONDS_PER_DAY) / 60 + 1;
      break;
  }
  
  pattern->end_minute = pattern->start_minute + minutes;

  synce_trace("pattern->start_minute/60: %u", pattern->start_minute / 60);
  synce_trace("pattern->end_minute  /60: %u", pattern->end_minute   / 60);

  success = true;

exit:
  return success;
}
Example #12
0
bool generator_run(Generator* self)
{
  unsigned i;
  bool success = false;

  for (i = 0; i < self->propval_count; i++)
  {
    uint16_t id = self->propvals[i].propid >> 16;
    GeneratorProperty* gp = 
      (GeneratorProperty*)s_hash_table_lookup(self->properties, &id);

    if (gp)
    {
      if (!gp->func(self, &self->propvals[i], self->cookie))
        goto exit;
    }
    else
    {
      char *tmp_str;
      switch (self->propvals[i].propid & 0xffff)
      {
      case CEVT_BLOB:
        synce_trace("Generator: Unhandled property, id: %04x, type: BLOB", id);
        break;
      case CEVT_BOOL:
        if (self->propvals[i].val.boolVal == FALSE)
          synce_trace("Generator: Unhandled property, id: %04x, type: bool:FALSE", id);
        else
          synce_trace("Generator: Unhandled property, id: %04x, type: bool:TRUE", id);
        break;
      case CEVT_FILETIME:
        if ((0 == self->propvals[i].val.filetime.dwLowDateTime) && (0 == self->propvals[i].val.filetime.dwHighDateTime))
          synce_trace("Generator: Unhandled property, id: %04x, type: filetime:NULL", id);
        else
        {
          time_t start_time;
          char buffer[32];
          parser_filetime_to_unix_time(&self->propvals[i].val.filetime, &start_time);
          strftime(buffer, sizeof(buffer), "%Y%m%dT%H%M%SZ", gmtime(&start_time));
          synce_trace("Generator: Unhandled property, id: %04x, type: filetime:%08x %08x=%s", id, self->propvals[i].val.filetime.dwHighDateTime,
                      self->propvals[i].val.filetime.dwLowDateTime,
                      buffer);
        }
        break;
      case CEVT_I2:
        synce_trace("Generator: Unhandled property, id: %04x, type: I2:%d", id, self->propvals[i].val.iVal);
        break;
      case CEVT_I4:
        synce_trace("Generator: Unhandled property, id: %04x, type: I4:%d", id, self->propvals[i].val.iVal);
        break;
      case CEVT_LPWSTR:
        tmp_str = wstr_to_current(self->propvals[i].val.lpwstr);
        synce_trace("Generator: Unhandled property, id: %04x, type: WSTR:%s", id, tmp_str);
        free(tmp_str);
        break;
      case CEVT_R8:
        synce_trace("Generator: Unhandled property, id: %04x, type: R8", id);
        break;
      case CEVT_UI2:
        synce_trace("Generator: Unhandled property, id: %04x, type: UI2:%u", id, self->propvals[i].val.uiVal);
        break;
      case CEVT_UI4:
        synce_trace("Generator: Unhandled property, id: %04x, type: UI4:%u", id, self->propvals[i].val.uiVal);
        break;
      default:
        synce_trace("Generator: Unhandled property, id: %04x, unknown type: %u", id, (self->propvals[i].propid & 0xffff));
        break;
      }
    }
  }

  success = true;

exit:
  return success;
}