⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.cxx

📁 完全免费的邮件发送程序。delphi 6.0
💻 CXX
📖 第 1 页 / 共 4 页
字号:
		{
		    error_code = GetLastError();
		    TRACE_MSG(("file::open: failed to read file in memory: "
			       "%s\n", get_error_text(buf, sizeof buf)));
		    CloseHandle(fd);
		    VirtualFree(vmem, 0, MEM_RELEASE);
		    return false;
		}
	    }
	    size_t page_map_size = ((mapped_size / page_size) + 31) >> 5;
	    dirty_page_map = new int[page_map_size];
	    memset(dirty_page_map, 0, sizeof(int)*page_map_size);
	}
	n_locked_pages = 0;
	if (max_locked_pages != 0) {
	    // check if we can use VirtualLock()
	    if (VirtualLock(base, page_size)) { 
		VirtualUnlock(base, page_size);
	    } else { 
		error_code = GetLastError();
		TRACE_MSG(("file::open: VirtualLock test failed: %s\n",
			   get_error_text(buf, sizeof buf)));
		max_locked_pages = 0;
	    }		
	}
	int log_flags = FILE_FLAG_SEQUENTIAL_SCAN;
	if (max_locked_pages == 0 && platform == VER_PLATFORM_WIN32_NT) { 
            log_flags |= FILE_FLAG_WRITE_THROUGH;
	}
	log = CreateFile(log_name, GENERIC_READ|GENERIC_WRITE, 0, NULL, 
			 OPEN_EXISTING, log_flags, NULL); 
	if (log == INVALID_HANDLE_VALUE) { 
	    if (GetLastError() == ERROR_FILE_NOT_FOUND) {
		log = CreateFile(log_name, GENERIC_READ|GENERIC_WRITE, 0, NULL,
				 CREATE_ALWAYS, log_flags, NULL); 
	    }
	    if (log == INVALID_HANDLE_VALUE) { 
		error_code = GetLastError();
		TRACE_MSG(("file::open: failed to create log file '%': %s\n", 
			   log_name, get_error_text(buf, sizeof buf)));
	      return_error:
		if (md != NULL) { 
		    UnmapViewOfFile(base);
		    CloseHandle(md);
		} else { 
		    VirtualFree(base, 0, MEM_RELEASE);
		}
		CloseHandle(fd);
		CloseHandle(log);
		delete[] dirty_page_map;
		return false;
	    }
	    if (size != 0 
		&& platform == VER_PLATFORM_WIN32_NT
		&& !VirtualProtect(base, size, PAGE_READONLY, &old_prot))
            {
		error_code = GetLastError();
		TRACE_MSG(("file::open: VirtualProtect failed for base=%p, "
			   "size=%ld: %s\n", 
			   base, size, get_error_text(buf, sizeof buf)));
		goto return_error;
	    }
	    next = chain;
	    chain = this;
	} else { 
	    next = chain;
	    chain = this;
	    recover_file();	
	    if (!commit()) { 
		chain = next;
		goto return_error;
	    }
	}
    } else { // non-shadow_pages_transaction mode
	int access_flags = (mode == map_file)
	    ? GENERIC_READ|GENERIC_WRITE : GENERIC_READ;
	int create_flags = (mode == map_file) 
	    ? OPEN_ALWAYS : OPEN_EXISTING;
	int hint_flags = (mode == load_in_memory) 
	    ? FILE_FLAG_SEQUENTIAL_SCAN : FILE_FLAG_RANDOM_ACCESS; 
	int share_mode = (prot == read_only) ? FILE_SHARE_READ|FILE_SHARE_WRITE : FILE_SHARE_READ;
	fd = CreateFile(name, access_flags, share_mode, NULL, 
			create_flags, hint_flags, NULL); 
	size = 0;
	base = NULL;
	if (fd != INVALID_HANDLE_VALUE) { 
	    DWORD read_bytes;
	    if (!ReadFile(fd, &base, sizeof base, &read_bytes, NULL)
		|| (read_bytes != 0 && read_bytes != sizeof base))
	    {
		error_code = GetLastError();
		TRACE_MSG(("file::open: failed to read file '%s': %s\n", 
			   name, get_error_text(buf, sizeof buf)));
		CloseHandle(fd);
		return false;
	    }
	    size = GetFileSize(fd, NULL);
	    if ((size & (allocation_granularity-1)) != 0
		&& prot != read_only 
		&& mode == copy_on_write_map 
		&& size < max_file_size)
	    {
		error_code = file_size_not_aligned;
		TRACE_MSG(("file::open: size of file '%s' is not aligned "
			   "on %ld\n", name, allocation_granularity));
		return false;
	    }
	    if (mode == copy_on_write_map) { 
		mapped_size = size;
		md = CreateFileMapping(fd, NULL, PAGE_WRITECOPY, 0, size,NULL);
		if (md == NULL) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::open: failed to create file mapping: "
			       "%s\n", get_error_text(buf, sizeof buf)));
		    CloseHandle(fd);
		    return false;
		}
		TRACE_MSG(("file::open: create file mapping: size=%ld\n",
			   size));
		void* p = MapViewOfFileEx(md, prot == read_only 
					  && platform == VER_PLATFORM_WIN32_NT 
					  ? FILE_MAP_READ : FILE_MAP_COPY, 
					  0, 0, size, base);
		if (p == NULL) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::open: failed to map view of file on "
			       "address %p: %s\n", 
			       base, get_error_text(buf, sizeof buf)));
		    p = MapViewOfFileEx(md, prot == read_only  
					&& platform == VER_PLATFORM_WIN32_NT
					? FILE_MAP_READ : FILE_MAP_COPY,
					0, 0, size, NULL);
		}
		if (p == NULL) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::open: failed to map view of file: %s\n", 
			       get_error_text(buf, sizeof buf)));
		    CloseHandle(md);
		    CloseHandle(fd);
		    return false;
		}
		base = (char*)p;
		TRACE_MSG(("file::open: map view of file on %p\n", base));
		if (prot != read_only && size < max_file_size) { 
		    mapped_size = max_file_size;
		    vmem = (char*)VirtualAlloc(base + size, mapped_size - size,
					       MEM_RESERVE, PAGE_READWRITE);
		    if (vmem == NULL) { 
			error_code = GetLastError();
			TRACE_MSG(("file::open: failed to allocate end of "
				   "region: base=%p, size=%ld: %s\n", 
				   base+size, mapped_size-size, 
				   get_error_text(buf, sizeof(buf))));
			UnmapViewOfFile(p);
			CloseHandle(md);
			CloseHandle(fd);
			return false;
		    }
		    TRACE_MSG(("file::open: virtual alloc: address=%p, "
			       "size=%ld\n", vmem, mapped_size));
		    assert(vmem == base + size);
		}  
	    } else if (mode == map_file) { 
		mapped_size = (prot == read_only || size > max_file_size)
		    ? size : max_file_size;
		md = CreateFileMapping(fd, NULL, PAGE_READWRITE, 0, 
				       mapped_size, NULL);
		if (md == NULL) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::open: failed to create file mapping: "
			       "%s\n", get_error_text(buf, sizeof buf)));
		    CloseHandle(fd);
		    return false;
		}
		TRACE_MSG(("file::open: create file mapping: size=%ld\n", 
			   size));
		void* p = MapViewOfFileEx(md, prot == read_only 
					  ?FILE_MAP_READ :FILE_MAP_ALL_ACCESS, 
					  0, 0, mapped_size, base);
		if (p == NULL) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::open: failed to map view of file on "
			       "address %p: %s\n", 
			       base, get_error_text(buf, sizeof buf)));
		    p = MapViewOfFileEx(md, prot == read_only  
					? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,
					0, 0, mapped_size, NULL);
		}
		if (p == NULL) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::open: failed to map view of file: %s\n", 
			       get_error_text(buf, sizeof buf)));
		    CloseHandle(md);
		    CloseHandle(fd);
		    return false;
		}
		base = (char*)p;
		TRACE_MSG(("file::open: map view of file on %p\n", base));
	    } else { // read file to memory
		mapped_size = (prot == read_only || size > max_file_size)
		    ? size : max_file_size;
		if (!read_file_in_memory()) { 
		    return false;
		}
		CloseHandle(fd);
		fd = INVALID_HANDLE_VALUE;
	    }
	} else { 
	    error_code = GetLastError();
	    if (error_code != ERROR_FILE_NOT_FOUND) { 
		TRACE_MSG(("file::open: failed to open file '%s': %s\n", 
		       name, get_error_text(buf, sizeof buf)));
		return false;
	    }
	    TRACE_MSG(("file::open: file '%s' not found\n", name));
	    if (prot == read_only) {
		TRACE_MSG(("file::open: failed to open in read only mode "
			   "unexisted file '%s'\n", name));
		return false;
	    }
	    mapped_size = max_file_size;
	    base = vmem = (char*)VirtualAlloc(NULL, mapped_size, 
					      MEM_RESERVE, PAGE_READWRITE);
	    if (base == NULL) {
		error_code = GetLastError();
		TRACE_MSG(("file::open: failed to virtual alloc: %s\n", 
			   get_error_text(buf, sizeof buf)));
		return false;
	    }
	}
    }
    error_code = ok;
    return true;
}

bool file::set_size(size_t new_size)
{
    if (new_size > mapped_size) { 
	error_code = file_mapping_size_exceeded;
	return false;
    } 
    if (mode == shadow_pages_transaction) {
	new_size = ALIGN(new_size, page_size);
	if (platform != VER_PLATFORM_WIN32_NT) { // Windows 95, uhh...
	    if (new_size > allocated_size) { 
		allocated_size = ALIGN(new_size, allocation_granularity);
		if (!VirtualAlloc(base+size, allocated_size-size, MEM_COMMIT,
				  PAGE_READWRITE))
		{
		    error_code = GetLastError();
		    return false;
		}
		unsigned page_no = size / page_size;
		size_t offs = size; 
		while (offs < allocated_size) {
		    dirty_page_map[page_no >> 5] |= 1 << (page_no & 0x1F);
		    offs += page_size;
		    page_no += 1;
		} 
	    }
	}
    } else { 
	if (mode != map_file) { 
	    new_size = ALIGN(new_size, allocation_granularity);
	    if (new_size > size) { 
		if (!VirtualAlloc(base+size, new_size-size, MEM_COMMIT,
				  PAGE_READWRITE))
		{
		    error_code = GetLastError();
		    return false;
		}
	    }
	}
    }
    size = new_size;
    error_code = ok;
    return true;
}

bool file::set_protection(access_prot prot)
{
    DWORD old_prot;
    if (platform == VER_PLATFORM_WIN32_NT || mode == map_file) { 
	if (!VirtualProtect(base, mapped_size, 
			    prot == file::read_only 
			    ? PAGE_READONLY 
			    : mode == copy_on_write_map 
			      ? PAGE_WRITECOPY : PAGE_READWRITE,
			    &old_prot))
	{
	    error_code = GetLastError();
	    return false;
	}
    }
    this->prot = prot;
    error_code = ok;
    return true;
}


bool file::commit()
{
    DWORD old_prot;
    if (mode != shadow_pages_transaction) { 
	error_code = not_in_transaction;
	return false;
    }
    if (n_locked_pages != 0 || platform != VER_PLATFORM_WIN32_NT) { 
	if (!flush_log_buffer()) { 
	    return false;
	}
    }
    if (platform == VER_PLATFORM_WIN32_NT) { 
	if (size > 0 && !FlushViewOfFile(base, size)) { 
	    error_code = GetLastError();
	    TRACE_MSG(("file::commit: FlushViewOfFile(%p, %ld) failed: %d\n",
		       base, size, error_code));
	    return false;
	}
    } else { 
	if (!write_dirty_pages_in_file()) { 
	    return false;
	}
    } 
    if (SetFilePointer(log, 0, NULL, FILE_BEGIN) != 0 || !SetEndOfFile(log)) { 
	error_code = GetLastError();
	TRACE_MSG(("file::commit: failed to truncate lof file: %d\n", 
		   error_code));
	return false;
    }
    if (size > 0 && platform == VER_PLATFORM_WIN32_NT && !VirtualProtect(base, size, PAGE_READONLY, &old_prot)){
	error_code = GetLastError();
	TRACE_MSG(("file::commit: VirtualProtect(%p, %ld) failed: %d\n",
		   base, size, error_code));
	return false;
    }
    error_code = ok;
    return true;
}

bool file::rollback()
{
    if (mode != shadow_pages_transaction) { 
	error_code = not_in_transaction;
	return false;
    }
    SetFilePointer(log, 0, NULL, FILE_BEGIN);
    return recover_file();
}

bool file::flush() 
{
    if (prot == read_only) {
	return true;
    }
    if (mode == shadow_pages_transaction) { 
	return commit();
    } else if (mode == map_file) { 
	if (!FlushViewOfFile(base, size)) {
	    error_code = GetLastError();
	    TRACE_MSG(("file::flush: failed to flush file mapping: %d\n",
		       error_code));
	    return false;
	}
	error_code = ok;
	return true;
    } else { // non-shadow_pages_transaction mode
	HANDLE tmp_fd = CreateFile(tmp_name, GENERIC_WRITE, 0, NULL, 
				   CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, 
				   NULL);
	if (tmp_fd == INVALID_HANDLE_VALUE) { 
	    error_code = GetLastError();
	    TRACE_MSG(("file::flush: failed to create temporary file '%s': "
		       "%d\n", tmp_name, error_code));
	    return false;
	}
	DWORD written_bytes;
	if (!WriteFile(tmp_fd, base, size, &written_bytes, NULL)
	    || written_bytes != size)
	{
	    error_code = GetLastError();
	    TRACE_MSG(("file::flush: failed to write %ld bytes to file '%s': "
		       "%d\n", size, tmp_name, error_code));
	    CloseHandle(tmp_fd);
	    return false;
	}
	CloseHandle(tmp_fd);
	if (platform == VER_PLATFORM_WIN32_NT) { 
	    if (fd != INVALID_HANDLE_VALUE) { 
		assert(md != NULL);
		if (!UnmapViewOfFile(base)) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::flush: failed to unmap %p: %d\n", 
			       base, error_code));
		    return false;
		}
		if (!CloseHandle(md)) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::flush: failed to close file mapping: "
			       "%d\n", error_code));
		    return false;
		}	    
		if (!CloseHandle(fd)) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::flush: failed to close file: %d\n",
			       error_code));
		    return false;
		}	    		    
		if (!MoveFileEx(tmp_name, name, MOVEFILE_REPLACE_EXISTING|
				MOVEFILE_WRITE_THROUGH) != 0)
		{ 
		    error_code = GetLastError();
		    TRACE_MSG(("file::flush: failed to reanme fileL %d\n",
			       error_code));
		    return false;
		}
		fd = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, 
				NULL, OPEN_EXISTING, 
				FILE_FLAG_SEQUENTIAL_SCAN, NULL); 
		if (fd == INVALID_HANDLE_VALUE) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::flush: failed to open file: %d\n", 
			       error_code));
		    return false;
		}
		assert(vmem != NULL);
		md = CreateFileMapping(fd, NULL, PAGE_WRITECOPY, 0, 
				       vmem - base, NULL);
		if (md == NULL) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::flush: failed to create file mapping: "
			       "base=%p, size=%ld: %d\n", 
			       base, vmem - base, error_code));
		    CloseHandle(fd);
		    return false;
		}
		void* p = MapViewOfFileEx(md, FILE_MAP_COPY, 
					  0, 0, vmem - base, base);
		if (p == NULL) { 
		    error_code = GetLastError();
		    TRACE_MSG(("file::flush: failed to map view of file on "
			       "address %p size %d: %d\n", 
			       base, vmem-base, error_code));
		    CloseHandle(fd);
		    CloseHandle(md);
		    return false;
		}
		assert(p == base);
	    } else { // just rename
		if (!MoveFileEx(tmp_name, name, MOVEFILE_REPLACE_EXISTING|
				MOVEFILE_WRITE_THROUGH) != 0)
		{ 
		    error_code = GetLastError();
		    TRACE_MSG(("file::flush: failed to reanme fileL %d\n",
			       error_code));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -