STM32F103C8 + W25Q64 USB Mass Storage Device
I did it! It works!

#define STORAGE_BLK_NBR      0x4000
#define STORAGE_BLK_SIZ        0x200

int8_t STORAGE_Read_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
        uint16_t blk_len) {
    w25qReadPage(buf, blk_addr * 2);
    w25qReadPage(buf + 256, blk_addr * 2 + 1);

    return (USBD_OK);
}

int8_t STORAGE_Write_FS(uint8_t lun, uint8_t *buf, uint32_t blk_addr,
        uint16_t blk_len) {
    w25qWritingByUSB(blk_addr, buf);
    return (USBD_OK);
}


void w25qReadPage(uint8_t *page, uint16_t pagenum) {

    uint8_t com[5] = { W25Q_READ_PAGE, (uint8_t) (pagenum &gt;&gt; 8),
            (uint8_t) (pagenum &amp; 0x00FF), 0x00, 0x00 };

    W25Q_CS_LO();

    HAL_SPI_Transmit(W25Q_SPI, com, 5, 10);

    HAL_SPI_Receive(W25Q_SPI, page, W25Q_PAGE_LEN, 10);
    W25Q_CS_HI();
}

void w25qWritePage(uint8_t *page, uint16_t pagenum) {

    uint8_t temp[4] = { W25Q_WRITE_ENABLE, 0x00, 0x00, 0x00 };

    w25qSetBlockProtect(0x00);

    W25Q_CS_LO();
    HAL_SPI_Transmit(W25Q_SPI, temp, 1, 10);
    W25Q_CS_HI();

    temp[0] = W25Q_PAGE_PROGRAM;
    temp[1] = (uint8_t) (pagenum &gt;&gt; 8);
    temp[2] = (uint8_t) (pagenum &amp; 0x00FF);
    temp[3] = 0x00;

    W25Q_CS_LO();
    HAL_SPI_Transmit(W25Q_SPI, temp, 4, 100);
    HAL_SPI_Transmit(W25Q_SPI, page, W25Q_PAGE_LEN, 10);
    W25Q_CS_HI();

    w25qWaitForReady();

    temp[0] = W25Q_WRRITE_DISABLE;

    W25Q_CS_LO();
    HAL_SPI_Transmit(W25Q_SPI, temp, 1, 10);
    W25Q_CS_HI();

    w25qSetBlockProtect(0x0F);

}

void w25qEraseSector(uint32_t sector) {
    w25qSetBlockProtect(0x00);

    sector = (sector &lt;&lt; 4);

    uint8_t com = W25Q_WRITE_ENABLE;
    uint8_t temp[4] = { W25Q_SECTOR_ERASE_4, (uint8_t) (sector &gt;&gt; 8),
            (uint8_t) (sector &amp; 0x00FF), 0x00 };

    W25Q_CS_LO();
    HAL_SPI_Transmit(W25Q_SPI, &amp;com, 1, 10);
    W25Q_CS_HI();

    W25Q_CS_LO();
    HAL_SPI_Transmit(W25Q_SPI, temp, 4, 10);
    W25Q_CS_HI();

    w25qWaitForReady();

    temp[0] = W25Q_WRRITE_DISABLE;

    W25Q_CS_LO();
    HAL_SPI_Transmit(W25Q_SPI, temp, 1, 10);
    W25Q_CS_HI();

    w25qSetBlockProtect(0x0F);
}

void w25qWritingByUSB(uint16_t dpagenum, uint8_t *bufByUSB) {

    uint8_t current_sector_buf[4096];
    uint16_t current_sector_addr = dpagenum / 8;
    uint16_t startPage = current_sector_addr * 16;
    int offset = 512 * (dpagenum % 8);

    for (uint16_t i = 0; i &lt; 16; i++) {
        w25qReadPage(current_sector_buf + 256 * i, startPage + i);
    }

    memcpy(current_sector_buf + offset, bufByUSB, 512);

    w25qEraseSector(current_sector_addr);

    startPage = current_sector_addr * 16;

    for (uint16_t i = 0; i &lt; 16; i++) {
        uint8_t buf[256];
        memcpy(buf, current_sector_buf + i * 256, 256);
        w25qWritePage(buf, startPage + i);
    }
}[

MSC_MEDIA_PACKET 512
USBD_MAX_STR_DESC_SIZ 512