Как совместно использовать память между услугами и пользовательскими процессами?

В этом нет ничего специфичного для Скалы. Это просто вопрос того, что целевой тип присваивания не имеет отношения к типу, в котором выполняется операция (в данном случае умножение).

Например, в C #:

using System;

class Program
{
    static void Main(string[] args)
    {
        int a = unchecked(86400000 * 150);
        long b = unchecked(86400000 * 150);
        long c = 86400000 * (long) 150;
        long d = 86400000 * 150L;
        Console.WriteLine(a); // 75098112
        Console.WriteLine(b); // 75098112
        Console.WriteLine(c); // 12960000000
        Console.WriteLine(d); // 12960000000
    }
}

Часть unchecked здесь заключается в том, что компилятор C # достаточно умен, чтобы понимать, что операция переполняется, но только потому, что оба операнда являются константами. Если бы любой операнд был переменной, все было бы хорошо без unchecked.

Аналогично в Java:

public class Program
{
    public static void main(String[] args)
    {
        int a = 86400000 * 150;
        long b = 86400000 * 150;
        long c = 86400000 * (long) 150;
        long d = 86400000 * 150L;
        System.out.println(a); // 75098112
        System.out.println(b); // 75098112
        System.out.println(c); // 12960000000
        System.out.println(d); // 12960000000
    }
}
7
задан Clay 22 May 2009 в 16:57
поделиться

1 ответ

Самый простой способ - заставить вашу службу создать общую память и указать DACL в CreateFileMapping, который предоставляет обычным пользователям доступ для чтения к общей памяти.

Обычные пользователи не имеют создать глобальную привилегию, но службы могут иметь эту привилегию. Если вам нужно, чтобы ваши пользователи создавали общую память, а затем проверяли ее службой, у вас может быть схема IPC, в которой ваш пользовательский код отправляет сообщение службе, содержащей дескриптор сопоставления файлов, а затем служба будет вызывать DuplicateHandle для получения ссылка на него. Это потребует, чтобы ваша служба запускалась с привилегией отладки.

Самый простой способ создать DACL - использовать ConvertStringSecurityDescriptorToSecurityDescriptor, который принимает строку в формате SDDL, определяющую ACL.

Написание безопасного кода содержит отличную главу о создании DACL с помощью SDDL.

// Error handling removed for brevity
SECURITY_ATTRIBUTES attributes;
ZeroMemory(&attributes, sizeof(attributes));
attributes.nLength = sizeof(attributes);
ConvertStringSecurityDescriptorToSecurityDescriptor(
         L"D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GR;;;IU)",
         SDDL_REVISION_1,
         &attributes.lpSecurityDescriptor,
         NULL);

CreateFileMapping(INVALID_HANDLE_VALUE, &attributes,
              PAGE_READWRITE, sizeHigh, sizeLow, L"Global\\MyObject");

LocalFree(attributes.lpSecurityDescriptor);

«D: P (A; OICI; GA ;;; SY) (A; OICI; GA ;;; BA) (A ; OICI; GR ;;; IU) "определяет DACL. D: P означает, что это DACL (вместо SACL ... вы редко используете SACL), за которым следуют несколько строк ACE, которые контролируют, кто получает доступ. Каждый из них - A (разрешить), разрешает объект и содержит наследование (OICI). Первым, кто предоставит полный доступ (GA - предоставить все) Системе (SY) и администраторам (BA, встроенным администраторам). Последний предоставляет чтение (GR) интерактивным пользователям (IU), которые являются пользователями, фактически вошедшими в сеанс.

Как только это будет сделано, обычные пользователи смогут вызвать OpenFileMapping, чтобы получить дескриптор общего сопоставления, и уметь отображать это в своем процессе. Поскольку обычные пользователи имеют ограниченные права на объект, они ' обязательно откройте его и сопоставьте только для чтения.

Если пользователям требуется доступ для записи, вы должны заменить GR на GWGR. Обратите внимание, что это небезопасно - ограниченный пользователь сможет изменить общую память, пока ваша служба читает и пытается проанализировать информацию, что приведет к сбою вашей службы.

11
ответ дан 6 December 2019 в 23:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: