static BOOL compare_surface(IDXGISurface *surface, const char *ref_sha1) { D3D10_MAPPED_TEXTURE2D mapped_texture; D3D10_TEXTURE2D_DESC texture_desc; DXGI_SURFACE_DESC surface_desc; ID3D10Resource *src_resource; ID3D10Texture2D *texture; ID3D10Device *device; HRESULT hr; BOOL ret; hr = IDXGISurface_GetDevice(surface, &IID_ID3D10Device, (void **)&device); ok(SUCCEEDED(hr), "Failed to get device, hr %#x.\n", hr); hr = IDXGISurface_QueryInterface(surface, &IID_ID3D10Resource, (void **)&src_resource); ok(SUCCEEDED(hr), "Failed to query resource interface, hr %#x.\n", hr); hr = IDXGISurface_GetDesc(surface, &surface_desc); ok(SUCCEEDED(hr), "Failed to get surface desc, hr %#x.\n", hr); texture_desc.Width = surface_desc.Width; texture_desc.Height = surface_desc.Height; texture_desc.MipLevels = 1; texture_desc.ArraySize = 1; texture_desc.Format = surface_desc.Format; texture_desc.SampleDesc = surface_desc.SampleDesc; texture_desc.Usage = D3D10_USAGE_STAGING; texture_desc.BindFlags = 0; texture_desc.CPUAccessFlags = D3D10_CPU_ACCESS_READ; texture_desc.MiscFlags = 0; hr = ID3D10Device_CreateTexture2D(device, &texture_desc, NULL, &texture); ok(SUCCEEDED(hr), "Failed to create texture, hr %#x.\n", hr); ID3D10Device_CopyResource(device, (ID3D10Resource *)texture, src_resource); hr = ID3D10Texture2D_Map(texture, 0, D3D10_MAP_READ, 0, &mapped_texture); ok(SUCCEEDED(hr), "Failed to map texture, hr %#x.\n", hr); ret = compare_sha1(mapped_texture.pData, mapped_texture.RowPitch, 4, texture_desc.Width, texture_desc.Height, ref_sha1); ID3D10Texture2D_Unmap(texture, 0); ID3D10Texture2D_Release(texture); ID3D10Resource_Release(src_resource); ID3D10Device_Release(device); return ret; }
/* * Decode UDP packet according to the given instructions! */ void udp_packet_decode(char * packet, char * fromIP){ struct dir_files_status_list *currTmp, *watchedTmp, *result; char pak[MAXBUF]; char fileSHA[SHA1_BYTES_LEN]; off_t file_len; int64_t clk, mod_time; char FromClient[255], file_name[255]; uint16_t tcp_port; int count =3 , i=0; char tmp[2], *file_full_path; /* First Decode each field and then print */ memcpy(pak, packet,MAXBUF); tmp[0] = pak[0]; tmp[1] = pak[1]; if(pak[2] != 0) perror("Not a Valid Message Field Client_name\n"); while(pak[count] != 0){ FromClient[i++] = pak[count++]; }FromClient[i] = '\0'; count++; memcpy(&tcp_port, &pak[count], 2); count+=2; memcpy(&clk, &pak[count],8); count+=8; if( (tmp[0] >= 3) && (tmp[0] <= 7)){ memcpy(&mod_time, &pak[count], 8); count += 9; i=0; while(pak[count] != 0){ file_name[i++] = pak[count++]; }file_name[i] = '\0'; count++; memcpy(fileSHA, &pak[count], SHA1_BYTES_LEN); count+=SHA1_BYTES_LEN; memcpy(&file_len, &pak[count], 8); count+=8; } /* Get the Lock and start printing!*/ pthread_mutex_lock(&print_mutex); switch(tmp[0]){ case(1): printf("\n\tSTATUS_MSG \n"); break; case(2): printf("\n\tNO_CHANGES_MSG \n"); break; case(3): printf("\n\tNEW_FILE_MSG \n"); pthread_mutex_lock(&file_list_mutex); watchedTmp = watched_files; currTmp = (struct dir_files_status_list * ) malloc( sizeof (struct dir_files_status_list)); if (!currTmp) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } currTmp->filename = (char *) malloc(strlen(file_name)); if (!currTmp->filename) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } strcpy(currTmp->filename, file_name); SGLIB_LIST_FIND_MEMBER(struct dir_files_status_list, watchedTmp, currTmp, ILIST_COMPARATOR, next, result); /* Case 1: the client does not have the file */ if(result == NULL){ /* Add file to the list and wait until its received to compare the SHA */ currTmp->size_in_bytes = file_len; currTmp->modifictation_time_from_epoch = mod_time; /* deep copy */ for(i = 0; i < SHA1_BYTES_LEN; i++) currTmp->sha1sum[i] = fileSHA[i]; SGLIB_SORTED_LIST_ADD(struct dir_files_status_list, watched_files, currTmp, ILIST_COMPARATOR, next); /* Ask for Transfer! */ i = udp_file_packet_encode(FILE_TRANSFER_REQUEST,client_name,TCP_PORT,&clk,&mod_time, file_name,fileSHA,file_len); currTmp->processed = TRUE; udp_packet_send(i); currTmp->processed = FALSE; } /* Case 2: the client DOES have the file listed */ else{ if(result->modifictation_time_from_epoch < mod_time){ /* Ask for Transfer! */ i = udp_file_packet_encode(FILE_TRANSFER_REQUEST,client_name,TCP_PORT,&clk,&mod_time, file_name,fileSHA,file_len); currTmp->processed = TRUE; udp_packet_send(i); currTmp->processed = FALSE; } free(currTmp); } pthread_mutex_unlock(&file_list_mutex); break; case(4): printf("\n\tFILE_CHANGED_MSG \n"); pthread_mutex_lock(&file_list_mutex); watchedTmp = watched_files; currTmp = (struct dir_files_status_list * ) malloc( sizeof (struct dir_files_status_list)); if (!currTmp) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } currTmp->filename = (char *) malloc(strlen(file_name)); if (!currTmp->filename) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } strcpy(currTmp->filename, file_name); SGLIB_LIST_FIND_MEMBER(struct dir_files_status_list, watchedTmp, currTmp, ILIST_COMPARATOR, next, result); /* Case 1: the client does not have the file, so add and transfer */ if(result == NULL){ /* Add file to the list and wait until its received to compare the SHA */ currTmp->size_in_bytes = file_len; currTmp->modifictation_time_from_epoch = mod_time; /* deep copy */ for(i = 0; i < SHA1_BYTES_LEN; i++) currTmp->sha1sum[i] = fileSHA[i]; SGLIB_SORTED_LIST_ADD(struct dir_files_status_list, watched_files, currTmp, ILIST_COMPARATOR, next); /* Ask for Transfer! */ i = udp_file_packet_encode(FILE_TRANSFER_REQUEST,client_name,TCP_PORT,&clk,&mod_time, file_name,fileSHA,file_len); /* file does not exist so its ok to set processed without checking */ currTmp->processed = TRUE; udp_packet_send(i); currTmp->processed = FALSE; } /* Case 2: the client DOES have the file listed so update it!*/ else{ /*Check timestamp */ if(result->modifictation_time_from_epoch < mod_time){ /* Add file to the list and wait until its received to compare the SHA */ result->size_in_bytes = file_len; result->modifictation_time_from_epoch = mod_time; /* deep copy */ for(i = 0; i < SHA1_BYTES_LEN; i++) result->sha1sum[i] = fileSHA[i]; /* Ask for Transfer! */ i = udp_file_packet_encode(FILE_TRANSFER_REQUEST,client_name,TCP_PORT,&clk,&mod_time, file_name,fileSHA,file_len); if (result->processed == FALSE){ result->processed = TRUE; udp_packet_send(i); result->processed = FALSE; } } free(currTmp); } pthread_mutex_unlock(&file_list_mutex); break; case(5): printf("\n\tFILE_DELETED_MSG \n"); pthread_mutex_lock(&file_list_mutex); watchedTmp = watched_files; currTmp = (struct dir_files_status_list * ) malloc( sizeof (struct dir_files_status_list)); if (!currTmp) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } currTmp->filename = (char *) malloc(strlen(file_name)); if (!currTmp->filename) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } strcpy(currTmp->filename, file_name); SGLIB_LIST_FIND_MEMBER(struct dir_files_status_list, watchedTmp, currTmp, ILIST_COMPARATOR, next, result); /* Case 1: the client does have the file */ if(result != NULL){ /* Check file similarity! */ if((file_len == result->size_in_bytes) && (compare_sha1(result->sha1sum,fileSHA) == 0)) { /* remove from dir */ file_full_path = (char * )malloc(strlen(file_name) + strlen(watched_dir)+1); strcpy(file_full_path,watched_dir); strcat(file_full_path,file_name); /*now remove from list*/ if (result->processed == FALSE){ result->processed = TRUE; if(remove(file_full_path) != 0 ){ fprintf(stderr,"[Cloudbox] Error deleting file %s\n",file_full_path); exit(EXIT_FAILURE); } SGLIB_LIST_DELETE(struct dir_files_status_list, watchedTmp, result, next); result->processed = FALSE; } free(file_full_path); } } /* Case 2: the client DOES NOT have the file Deleted */ else{ free(currTmp); } pthread_mutex_unlock(&file_list_mutex); break; case(6): printf("\n\tFILE_TRANSFER_REQUEST \n"); pthread_mutex_lock(&file_list_mutex); watchedTmp = watched_files; currTmp = (struct dir_files_status_list * ) malloc( sizeof (struct dir_files_status_list)); if (!currTmp) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } currTmp->filename = (char *) malloc(strlen(file_name)); if (!currTmp->filename) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } strcpy(currTmp->filename, file_name); SGLIB_LIST_FIND_MEMBER(struct dir_files_status_list, watchedTmp, currTmp, ILIST_COMPARATOR, next, result); if((result != NULL) && (compare_sha1(result->sha1sum,fileSHA) == 0) ){ /* its my file the other client is looking for! */ if (result->processed == FALSE){ result->processed = TRUE; send_file(fromIP, tcp_port, file_name); result->processed = FALSE; } } pthread_mutex_unlock(&file_list_mutex); free(currTmp->filename); free(currTmp); break; case(7): printf("\n\tFILE_TRANSFER_OFFER \n"); pthread_mutex_lock(&file_list_mutex); watchedTmp = watched_files; currTmp = (struct dir_files_status_list * ) malloc( sizeof (struct dir_files_status_list)); if (!currTmp) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } currTmp->filename = (char *) malloc(strlen(file_name)); if (!currTmp->filename) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } strcpy(currTmp->filename, file_name); SGLIB_LIST_FIND_MEMBER(struct dir_files_status_list, watchedTmp, currTmp, ILIST_COMPARATOR, next, result); /* Case 1: the client does not have the file */ if(result == NULL){ /* Add file to the list and wait until its received to compare the SHA */ currTmp->size_in_bytes = file_len; currTmp->modifictation_time_from_epoch = mod_time; /* deep copy */ for(i = 0; i < SHA1_BYTES_LEN; i++) currTmp->sha1sum[i] = fileSHA[i]; SGLIB_SORTED_LIST_ADD(struct dir_files_status_list, watched_files, currTmp, ILIST_COMPARATOR, next); /* Ask for Transfer! */ i = udp_file_packet_encode(FILE_TRANSFER_REQUEST,client_name,TCP_PORT,&clk,&mod_time, file_name,fileSHA,file_len); currTmp->processed = TRUE; udp_packet_send(i); currTmp->processed = FALSE; } /* Case 2: the client DOES have the file listed */ else{ free(currTmp); } pthread_mutex_unlock(&file_list_mutex); break; case(8): printf("\n\tDIR_EMPTY \n"); pthread_mutex_unlock(&print_mutex); /* sleep is useful in case we remove all files from directory and we have both DELETE FILE and EMPTY DIR messages */ sleep(2); watchedTmp = listWatchedDir(watched_dir); watched_files = watchedTmp; pthread_mutex_lock(&print_mutex); pthread_mutex_lock(&file_list_mutex); currTmp = (struct dir_files_status_list * ) malloc( sizeof (struct dir_files_status_list)); if (!currTmp) { fprintf(stderr, "malloc() failed: insufficient memory!\n"); exit(EXIT_FAILURE); } int listlen=0; SGLIB_LIST_LEN(struct dir_files_status_list,watchedTmp,next, listlen); UNUSED(currTmp); /* If other client is empty start updating him */ if(listlen > 0){ SGLIB_LIST_MAP_ON_ELEMENTS(struct dir_files_status_list, watchedTmp, currTmp, next, { /* Offer file! */ i = udp_file_packet_encode(FILE_TRANSFER_OFFER,client_name,TCP_PORT,&clk,&currTmp->modifictation_time_from_epoch, currTmp->filename,currTmp->sha1sum,currTmp->size_in_bytes); if (currTmp->processed == FALSE){ currTmp->processed = TRUE; udp_packet_send(i); currTmp->processed = FALSE; } });