Example #1
0
BOOL _CeFindAllDatabases(/*{{{*/
                RapiContext *context,
		DWORD dwDbaseType,
		WORD wFlags,
		LPWORD cFindData,
		LPLPCEDB_FIND_DATA ppFindData)
{
	uint16_t count;

	rapi_database_trace("begin");

	rapi_context_begin_command(context, 0x2c);

        if ((!cFindData) || (!ppFindData)) {
                context->last_error = ERROR_INVALID_PARAMETER;
                return false;
        }

	rapi_buffer_write_uint32(context->send_buffer, dwDbaseType);
	rapi_buffer_write_uint16(context->send_buffer, wFlags);

	if ( !rapi_context_call(context) )
		return false;

	rapi_buffer_read_uint16(context->recv_buffer, &count);

	rapi_database_trace("found 0x%04x databases", count);

	if (cFindData)
		*cFindData = count;

	if (ppFindData && count > 0)
	{
		LPCEDB_FIND_DATA find_data = calloc(count, sizeof(CEDB_FIND_DATA));

		*ppFindData = find_data;

		if (find_data)
		{
			uint32_t i;
			uint32_t name_size = 0;

			for(i = 0; i < count; i++)
			{
				if (wFlags & FAD_OID)
				{
					if ( !rapi_buffer_read_uint32(context->recv_buffer, &find_data[i].OidDb) )
						goto fail;
					rapi_database_trace("oid=%08x", find_data[i].OidDb);
				}

				if (wFlags & FAD_NAME)
					rapi_buffer_read_uint32(context->recv_buffer, &name_size);

				if (wFlags & FAD_FLAGS)
					rapi_buffer_read_uint32(context->recv_buffer, &find_data[i].DbInfo.dwFlags);

				if (wFlags & FAD_NAME)
				{
					if (name_size)
					{
						rapi_buffer_read_data(context->recv_buffer, find_data[i].DbInfo.szDbaseName, name_size * sizeof(WCHAR) );
						rapi_database_trace_wstr(find_data[i].DbInfo.szDbaseName);
					}
					else
					{
						rapi_database_error("name_size is 0");
						goto fail;
					}
				}

				if (wFlags & FAD_TYPE)
					rapi_buffer_read_uint32(context->recv_buffer, &find_data[i].DbInfo.dwDbaseType);

				if (wFlags & FAD_NUM_RECORDS)
					rapi_buffer_read_uint16(context->recv_buffer, &find_data[i].DbInfo.wNumRecords);

				if (wFlags & FAD_NUM_SORT_ORDER)
					rapi_buffer_read_uint16(context->recv_buffer, &find_data[i].DbInfo.wNumSortOrder);

				if (wFlags & FAD_SIZE)
					rapi_buffer_read_uint32(context->recv_buffer, &find_data[i].DbInfo.dwSize);

				if (wFlags & FAD_LAST_MODIFIED)
				{
					rapi_buffer_read_uint32(context->recv_buffer, &find_data[i].DbInfo.ftLastModified.dwLowDateTime);
					rapi_buffer_read_uint32(context->recv_buffer, &find_data[i].DbInfo.ftLastModified.dwHighDateTime);
				}

				if (wFlags & FAD_SORT_SPECS)
				{
					int j;

					for (j = 0; j < CEDB_MAXSORTORDER; j++)
					{
						rapi_buffer_read_uint32(context->recv_buffer, &find_data[i].DbInfo.rgSortSpecs[j].propid);
						rapi_buffer_read_uint32(context->recv_buffer, &find_data[i].DbInfo.rgSortSpecs[j].dwFlags);
					}
				}
			} /* for each database */
		}
		else
		{
			rapi_database_error("failed to allocate memory");
			goto fail;
		}

		*ppFindData = find_data;
	}

	return true;

fail:
	if (ppFindData && *ppFindData)
		free(ppFindData);
	return false;
}/*}}}*/
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 #3
0
CEOID _CeReadRecordProps(/*{{{*/
                RapiContext *context,
		HANDLE hDbase,
		DWORD dwFlags,
		LPWORD lpcPropID,
		CEPROPID *rgPropID,
		LPBYTE *lplpBuffer,
		LPDWORD lpcbBuffer)
{

	/* need to do something with rgPropID */

	CEOID return_value = 0;
	uint16_t prop_id_count = 0;
	uint32_t recv_size = 0;
	size_t out_size = 0;
	uint32_t i;
	unsigned char* recv_buffer = NULL;
	unsigned char* out_buffer = NULL;
	size_t recv_propval_size = 0;
	size_t extra_data_size = 0;
	size_t out_propval_size = 0;

	rapi_database_trace("begin");

	if (! lpcbBuffer ) {
	  return_value = 0;
	  context->last_error = ERROR_INVALID_PARAMETER;
	  goto exit;
	}

	rapi_context_begin_command(context, 0x10);
	rapi_buffer_write_uint32(context->send_buffer, hDbase);
	rapi_buffer_write_uint32(context->send_buffer, dwFlags);
	rapi_buffer_write_uint32(context->send_buffer, 0);
	rapi_buffer_write_uint32(context->send_buffer, 0);
	rapi_buffer_write_uint32(context->send_buffer, 0);
	rapi_buffer_write_uint16(context->send_buffer, 0);

	if ( !rapi_context_call(context) )
		goto fail;

	if ( !rapi_buffer_read_uint32(context->recv_buffer, &context->last_error) )
		goto fail;
	rapi_database_trace("context->last_error=0x%08x", context->last_error);

	if ( !rapi_buffer_read_uint32(context->recv_buffer, &return_value) )
		goto fail;
	rapi_database_trace("return_value=0x%08x", return_value);

	if ( !rapi_buffer_read_uint32(context->recv_buffer, &recv_size) )
		goto fail;
	rapi_database_trace("received size=%i", recv_size);

	if ( !rapi_buffer_read_uint16(context->recv_buffer, &prop_id_count) )
		goto fail;
	rapi_database_trace("prop_id_count=%i", prop_id_count);

	if (lpcPropID)
		*lpcPropID = prop_id_count;

	/* 
	 *  the data buffer we recieve consists of CEPROPVAL items, followed by
	 *  misc data eg. strings
	 *
	 *  we cannot do a direct cast to a CEPROPVAL array because we cannot guarantee
	 *  that pointer items will be the same size on both platforms
	 */

	/* size of CEPROPVAL over the wire is 16 bytes, ie pointers are 32 bit */
	recv_propval_size = 16 * prop_id_count;
	rapi_database_trace("original propval size = %u", recv_propval_size);

	extra_data_size = recv_size - recv_propval_size;
	rapi_database_trace("extra data size = %u", extra_data_size);

	out_propval_size = sizeof(CEPROPVAL) * prop_id_count;
	rapi_database_trace("new provpval size = %u", out_propval_size);

	out_size = extra_data_size + out_propval_size;
	rapi_database_trace("out buffer size = %u", out_size);

	if (lplpBuffer)
	{
		if (*lplpBuffer != NULL) {
		  if (*lpcbBuffer < out_size) {
		    if  (dwFlags & CEDB_ALLOWREALLOC)
		      *lplpBuffer = realloc(*lplpBuffer, out_size);
		    else
		      {
			context->last_error = ERROR_INSUFFICIENT_BUFFER;
			return_value = 0;
			*lpcbBuffer = out_size;
			goto exit;
		      }
		  }
		} else
		  *lplpBuffer = malloc(out_size);

		if (!(*lplpBuffer)) {
		  context->last_error = ERROR_NOT_ENOUGH_MEMORY;
		  return_value = 0;
		  *lpcbBuffer = out_size;
		  goto exit;
		}

		out_buffer = *lplpBuffer;

		recv_buffer = calloc(1, recv_size);
		if (!recv_buffer) {
		  rapi_database_error("failed to allocate 0x%08x bytes", recv_size);
		  context->last_error = ERROR_NOT_ENOUGH_MEMORY;
		  return_value = 0;
		  *lpcbBuffer = out_size;
		  goto exit;
		}

		CEPROPVAL* propval;
		unsigned char * buf_pos = recv_buffer;

		if ( !rapi_buffer_read_data(context->recv_buffer, recv_buffer, recv_size) )
		  {
		    rapi_database_error("failed to read buffer");
		    goto fail;
		  }

		memcpy(out_buffer + out_propval_size, recv_buffer + recv_propval_size, extra_data_size);

		propval = (CEPROPVAL*)out_buffer;

		rapi_database_trace("buffer = %p", recv_buffer);

		for (i = 0; i < prop_id_count; i++)
		  {

		    propval[i].propid = letoh32(*((uint32_t*)buf_pos));
		    buf_pos = buf_pos + 4;
		    propval[i].wLenData = letoh16(*((uint16_t*)buf_pos));
		    buf_pos = buf_pos + 2;
		    propval[i].wFlags = letoh16(*((uint16_t*)buf_pos));
		    buf_pos = buf_pos + 2;

		    rapi_database_trace("propval[%i].propid = %08x", i, propval[i].propid);


		    switch (propval[i].propid & 0xffff)
		      {

		      case CEVT_BLOB:

			rapi_database_trace("CEVT_BLOB");

			propval[i].val.blob.dwCount = letoh32(*((uint32_t*)buf_pos));
			buf_pos = buf_pos + 4;

			propval[i].val.blob.lpb = letoh32(*((uint32_t*)buf_pos)) - recv_propval_size + (sizeof(CEPROPVAL) * prop_id_count) + out_buffer;
			buf_pos = buf_pos + 4;

			rapi_database_trace("propval[%i].val.blob.dwCount = %08x",
					    i, propval[i].val.blob.dwCount);
			rapi_database_trace("propval[%i].val.blob.lpb = %08x",
					    i, propval[i].val.blob.lpb);

			rapi_database_trace("blob=%s",(char*)propval[i].val.blob.lpb);
			break;

		      case CEVT_LPWSTR:

			rapi_database_trace("CEVT_LPWSTR");

			propval[i].val.lpwstr = (LPWSTR)(letoh32(*((uint32_t*)buf_pos)) - recv_propval_size + (sizeof(CEPROPVAL) * prop_id_count) + out_buffer);
			buf_pos = buf_pos + 8;

			rapi_database_trace("string offset = %p", propval[i].val.lpwstr);
			rapi_database_trace_wstr(propval[i].val.lpwstr);
			rapi_database_trace("propval[i].val.lpwstr = %p", propval[i].val.lpwstr);
			break;

		      case CEVT_I2:
			rapi_database_trace("CEVT_I2");
			propval[i].val.iVal = letoh16(*((int16_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_I4:
			rapi_database_trace("CEVT_I4");
			propval[i].val.lVal = letoh32(*((int32_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_R8:

			/* TODO: convert endianness for this, need to set up 64 swap in synce.h */

			rapi_database_trace("CEVT_R8");
			memcpy(&(propval[i].val), buf_pos, 8);
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_BOOL:
			rapi_database_trace("CEVT_BOOL");
			propval[i].val.boolVal = letoh16(*((int16_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_UI2:
			rapi_database_trace("CEVT_UI2");
			propval[i].val.uiVal = letoh16(*((uint16_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_UI4:
			rapi_database_trace("CEVT_UI4");
			propval[i].val.ulVal = letoh32(*((uint32_t*)buf_pos));
			buf_pos = buf_pos + 8;
			break;
		      case CEVT_FILETIME:
			rapi_database_trace("CEVT_FILETIME");
			propval[i].val.filetime.dwLowDateTime = letoh32(*((uint32_t*)buf_pos));
			buf_pos += 4;
			propval[i].val.filetime.dwHighDateTime = letoh32(*((uint32_t*)buf_pos));
			buf_pos += 4;
			break;
		      }
		  }

		free(recv_buffer);
	}

	*lpcbBuffer = out_size;

exit:
	return return_value;

fail:
 	rapi_database_error("failed");
	if (recv_buffer)
	  free(recv_buffer);
	return 0;
}/*}}}*/