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; }
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; }/*}}}*/